99 */
1010public final class DynamicIntArray {
1111
12+ // Growth factor for array expansion
13+ private static final double GROWTH_FACTOR = 1.5 ;
14+ // Minimum capacity increment to avoid small incremental growth
15+ private static final int MIN_CAPACITY_INCREMENT = 10 ;
16+
1217 private final int maxLength ;
1318 private int [] array ;
1419 private int firstIndex ;
@@ -33,7 +38,8 @@ public DynamicIntArray(int maxLength) {
3338 /**
3439 * Sets the value at the specified index.
3540 * If this is the first element, the array is created.
36- * If the index is lower than the current firstIndex, the array is reallocated.
41+ * If the index is lower than the current firstIndex or higher than the current lastIndex,
42+ * the array is reallocated with a growth strategy to reduce frequent reallocations.
3743 *
3844 * @param index the index at which to set the value
3945 * @param value the value to set
@@ -43,42 +49,81 @@ public void set(int index, int value) {
4349 throw new ArrayIndexOutOfBoundsException (index );
4450 }
4551 if (array == null ) {
46- // First element, create the array with size 1
47- array = new int [1 ];
52+ // First element, create the array with initial capacity
53+ var initialCapacity = Math .min (MIN_CAPACITY_INCREMENT , maxLength );
54+ array = new int [initialCapacity ];
4855 firstIndex = index ;
4956 lastIndex = index ;
5057 array [0 ] = value ;
5158 } else if (index < firstIndex ) {
5259 // New index is lower than first index, need to reallocate
53- int newSize = lastIndex - index + 1 ;
54- int [] newArray = new int [ newSize ] ;
60+ var currentSize = lastIndex - firstIndex + 1 ;
61+ var offset = firstIndex - index ;
5562
56- // Copy existing elements to new array with offset
57- int offset = firstIndex - index ;
58- System . arraycopy ( array , 0 , newArray , offset , lastIndex - firstIndex + 1 );
63+ // Calculate new capacity with growth strategy
64+ var requiredCapacity = currentSize + offset ;
65+ var newCapacity = calculateNewCapacity ( requiredCapacity );
5966
60- // Update first index and array
61- firstIndex = index ;
67+ // Copy existing elements to new array with offset
68+ var newArray = new int [newCapacity ];
69+ System .arraycopy (array , 0 , newArray , offset , currentSize );
6270 array = newArray ;
71+ firstIndex = index ;
6372 array [0 ] = value ;
6473 } else if (index > lastIndex ) {
6574 // New index is higher than last index, need to expand
66- int newSize = index - firstIndex + 1 ;
67- int [] newArray = new int [newSize ];
75+ var currentSize = lastIndex - firstIndex + 1 ;
76+ var newSize = index - firstIndex + 1 ;
77+
78+ if (newSize > array .length ) {
79+ // Calculate new capacity with growth strategy
80+ var newCapacity = calculateNewCapacity (newSize );
6881
69- // Copy existing elements to new array
70- System .arraycopy (array , 0 , newArray , 0 , array .length );
82+ // Copy existing elements to new array
83+ var newArray = new int [newCapacity ];
84+ System .arraycopy (array , 0 , newArray , 0 , currentSize );
85+ array = newArray ;
86+ }
7187
72- // Update last index and array
88+ // Update last index
7389 lastIndex = index ;
74- array = newArray ;
7590 array [index - firstIndex ] = value ;
7691 } else {
7792 // Index is within existing range
7893 array [index - firstIndex ] = value ;
7994 }
8095 }
8196
97+ /**
98+ * Calculates the new capacity based on the required capacity and growth strategy.
99+ *
100+ * @param requiredCapacity the minimum capacity needed
101+ * @return the new capacity
102+ */
103+ private int calculateNewCapacity (int requiredCapacity ) {
104+ var currentCapacity = array != null ? array .length : 0 ;
105+
106+ if (requiredCapacity <= currentCapacity ) {
107+ return currentCapacity ;
108+ }
109+
110+ // Calculate new capacity using growth factor
111+ var newCapacity = (int ) (currentCapacity * GROWTH_FACTOR );
112+
113+ // Ensure minimum increment
114+ if (newCapacity - currentCapacity < MIN_CAPACITY_INCREMENT ) {
115+ newCapacity = currentCapacity + MIN_CAPACITY_INCREMENT ;
116+ }
117+
118+ // Ensure new capacity is at least the required capacity
119+ if (newCapacity < requiredCapacity ) {
120+ newCapacity = requiredCapacity ;
121+ }
122+
123+ // Ensure new capacity doesn't exceed maxLength
124+ return Math .min (newCapacity , maxLength );
125+ }
126+
82127 /**
83128 * Gets the value at the specified index.
84129 *
@@ -144,10 +189,19 @@ int length() {
144189 return lastIndex + 1 ;
145190 }
146191
192+ /**
193+ * Clears the array by setting all values to 0.
194+ * The array structure is preserved, only the values are reset.
195+ */
147196 public void clear () {
148- // Fill rather than reallocate.
149- // We keep the original bounds, assuming the array is likely to be filled up again.
150- Arrays .fill (array , 0 );
197+ // If array is null, there's nothing to clear
198+ if (array == null ) {
199+ return ;
200+ }
201+
202+ // Only clear the used portion of the array (from firstIndex to lastIndex)
203+ // This is more efficient for large arrays with sparse indices
204+ Arrays .fill (array , 0 , lastIndex - firstIndex + 1 , 0 );
151205 }
152206
153- }
207+ }
0 commit comments