Skip to content

Commit 4f7957f

Browse files
authored
Enhance docs, add more tests in DynamicArray (#5952)
1 parent d868982 commit 4f7957f

File tree

2 files changed

+88
-22
lines changed

2 files changed

+88
-22
lines changed

src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java

+85-22
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,24 @@
1010
import java.util.stream.StreamSupport;
1111

1212
/**
13-
* This class implements a dynamic array.
13+
* This class implements a dynamic array, which can grow or shrink in size
14+
* as elements are added or removed. It provides an array-like interface
15+
* with methods to add, remove, and access elements, along with iterators
16+
* to traverse the elements.
1417
*
15-
* @param <E> the type that each index of the array will hold
18+
* @param <E> the type of elements that this array can hold
1619
*/
1720
public class DynamicArray<E> implements Iterable<E> {
1821

1922
private static final int DEFAULT_CAPACITY = 16;
2023
private int size;
21-
private int modCount; // Tracks structural modifications for the iterator
24+
private int modCount; // Tracks structural modifications for iterator integrity
2225
private Object[] elements;
2326

2427
/**
25-
* Constructor with initial capacity.
28+
* Constructs a new DynamicArray with the specified initial capacity.
2629
*
27-
* @param capacity the starting length of the desired array
30+
* @param capacity the initial capacity of the array
2831
* @throws IllegalArgumentException if the specified capacity is negative
2932
*/
3033
public DynamicArray(final int capacity) {
@@ -37,14 +40,15 @@ public DynamicArray(final int capacity) {
3740
}
3841

3942
/**
40-
* No-args constructor with default capacity.
43+
* Constructs a new DynamicArray with a default initial capacity.
4144
*/
4245
public DynamicArray() {
4346
this(DEFAULT_CAPACITY);
4447
}
4548

4649
/**
47-
* Adds an element to the array. If full, creates a new array with double the size.
50+
* Adds an element to the end of the array. If the array is full, it
51+
* creates a new array with double the size to accommodate the new element.
4852
*
4953
* @param element the element to be added to the array
5054
*/
@@ -55,11 +59,11 @@ public void add(final E element) {
5559
}
5660

5761
/**
58-
* Places an element at the desired index, expanding capacity if necessary.
62+
* Places an element at the specified index, expanding capacity if necessary.
5963
*
60-
* @param index the index for the element to be placed
61-
* @param element the element to be inserted
62-
* @throws IndexOutOfBoundsException if n is less than 0 or greater or equal to the number of elements in the array
64+
* @param index the index at which the element is to be placed
65+
* @param element the element to be inserted at the specified index
66+
* @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the number of elements
6367
*/
6468
public void put(final int index, E element) {
6569
if (index < 0) {
@@ -74,11 +78,11 @@ public void put(final int index, E element) {
7478
}
7579

7680
/**
77-
* Gets the element at a given index.
81+
* Retrieves the element at the specified index.
7882
*
79-
* @param index the desired index of the element
83+
* @param index the index of the element to retrieve
8084
* @return the element at the specified index
81-
* @throws IndexOutOfBoundsException if n is less than 0 or greater or equal to the number of elements in the array
85+
* @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the current size
8286
*/
8387
@SuppressWarnings("unchecked")
8488
public E get(final int index) {
@@ -89,11 +93,11 @@ public E get(final int index) {
8993
}
9094

9195
/**
92-
* Removes an element from the array.
96+
* Removes and returns the element at the specified index.
9397
*
9498
* @param index the index of the element to be removed
95-
* @return the element removed
96-
* @throws IndexOutOfBoundsException if n is less than 0 or greater or equal to the number of elements in the array
99+
* @return the element that was removed from the array
100+
* @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the current size
97101
*/
98102
public E remove(final int index) {
99103
if (index < 0 || index >= size) {
@@ -106,34 +110,50 @@ public E remove(final int index) {
106110
}
107111

108112
/**
109-
* Gets the size of the array.
113+
* Returns the current number of elements in the array.
110114
*
111-
* @return the size
115+
* @return the number of elements in the array
112116
*/
113117
public int getSize() {
114118
return size;
115119
}
116120

117121
/**
118-
* Checks if the array is empty.
122+
* Checks whether the array is empty.
119123
*
120124
* @return true if the array contains no elements, false otherwise
121125
*/
122126
public boolean isEmpty() {
123127
return size == 0;
124128
}
125129

130+
/**
131+
* Returns a sequential stream with this collection as its source.
132+
*
133+
* @return a stream of the elements in the array
134+
*/
126135
public Stream<E> stream() {
127136
return StreamSupport.stream(spliterator(), false);
128137
}
129138

139+
/**
140+
* Ensures that the array has enough capacity to hold the specified number of elements.
141+
*
142+
* @param minCapacity the minimum capacity required
143+
*/
130144
private void ensureCapacity(int minCapacity) {
131145
if (minCapacity > elements.length) {
132146
int newCapacity = Math.max(elements.length * 2, minCapacity);
133147
elements = Arrays.copyOf(elements, newCapacity);
134148
}
135149
}
136150

151+
/**
152+
* Removes the element at the specified index without resizing the array.
153+
* This method shifts any subsequent elements to the left and clears the last element.
154+
*
155+
* @param index the index of the element to remove
156+
*/
137157
private void fastRemove(int index) {
138158
int numMoved = size - index - 1;
139159
if (numMoved > 0) {
@@ -142,31 +162,58 @@ private void fastRemove(int index) {
142162
elements[--size] = null; // Clear to let GC do its work
143163
}
144164

165+
/**
166+
* Returns a string representation of the array, including only the elements that are currently stored.
167+
*
168+
* @return a string containing the elements in the array
169+
*/
145170
@Override
146171
public String toString() {
147172
return Arrays.toString(Arrays.copyOf(elements, size));
148173
}
149174

175+
/**
176+
* Returns an iterator over the elements in this array in proper sequence.
177+
*
178+
* @return an Iterator over the elements in the array
179+
*/
150180
@Override
151181
public Iterator<E> iterator() {
152182
return new DynamicArrayIterator();
153183
}
154184

185+
/**
186+
* Private iterator class for the DynamicArray.
187+
*/
155188
private final class DynamicArrayIterator implements Iterator<E> {
156189

157190
private int cursor;
158191
private int expectedModCount;
159192

193+
/**
194+
* Constructs a new iterator for the dynamic array.
195+
*/
160196
DynamicArrayIterator() {
161197
this.expectedModCount = modCount;
162198
}
163199

200+
/**
201+
* Checks if there are more elements in the iteration.
202+
*
203+
* @return true if there are more elements, false otherwise
204+
*/
164205
@Override
165206
public boolean hasNext() {
166207
checkForComodification();
167208
return cursor < size;
168209
}
169210

211+
/**
212+
* Returns the next element in the iteration.
213+
*
214+
* @return the next element in the iteration
215+
* @throws NoSuchElementException if the iteration has no more elements
216+
*/
170217
@Override
171218
@SuppressWarnings("unchecked")
172219
public E next() {
@@ -177,22 +224,38 @@ public E next() {
177224
return (E) elements[cursor++];
178225
}
179226

227+
/**
228+
* Removes the last element returned by this iterator.
229+
*
230+
* @throws IllegalStateException if the next method has not yet been called, or the remove method has already been called after the last call to the next method
231+
*/
180232
@Override
181233
public void remove() {
182234
if (cursor <= 0) {
183-
throw new IllegalStateException();
235+
throw new IllegalStateException("Cannot remove element before calling next()");
184236
}
185237
checkForComodification();
186238
DynamicArray.this.remove(--cursor);
187-
expectedModCount = ++modCount;
239+
expectedModCount = modCount;
188240
}
189241

242+
/**
243+
* Checks for concurrent modifications to the array during iteration.
244+
*
245+
* @throws ConcurrentModificationException if the array has been modified structurally
246+
*/
190247
private void checkForComodification() {
191248
if (modCount != expectedModCount) {
192249
throw new ConcurrentModificationException();
193250
}
194251
}
195252

253+
/**
254+
* Performs the given action for each remaining element in the iterator until all elements have been processed.
255+
*
256+
* @param action the action to be performed for each element
257+
* @throws NullPointerException if the specified action is null
258+
*/
196259
@Override
197260
public void forEachRemaining(Consumer<? super E> action) {
198261
Objects.requireNonNull(action);

src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java

+3
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ public void setUp() {
2424
public void testGetElement() {
2525
array.add("Alice");
2626
array.add("Bob");
27+
array.add("Charlie");
28+
array.add("David");
2729
assertEquals("Bob", array.get(1));
2830
}
2931

3032
@Test
3133
public void testGetInvalidIndex() {
3234
assertThrows(IndexOutOfBoundsException.class, () -> array.get(-1));
3335
assertThrows(IndexOutOfBoundsException.class, () -> array.get(10));
36+
assertThrows(IndexOutOfBoundsException.class, () -> array.get(100));
3437
}
3538

3639
@Test

0 commit comments

Comments
 (0)