grow the array only by 50%
The old implementation grew the array by 100% with each resize. The new implementation reduces the memory usage for, especially for large lists. The new algorithm is overflow-concious.
This commit is contained in:
@@ -13,6 +13,11 @@ public class IntList {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
/**
|
||||
* The maximum size of an array.
|
||||
*/
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
private int[] data;
|
||||
|
||||
private int index = 0;
|
||||
@@ -33,16 +38,16 @@ public class IntList {
|
||||
* if initial capacity is negative
|
||||
*/
|
||||
public IntList(final int initialCapacity) {
|
||||
if (initialCapacity < 0) {
|
||||
throw new IllegalArgumentException("initial capacity must not be negative");
|
||||
if (initialCapacity < 0 || initialCapacity > MAX_ARRAY_SIZE) {
|
||||
throw new IllegalArgumentException(
|
||||
"initial capacity must not be negative and not larger than " + MAX_ARRAY_SIZE);
|
||||
}
|
||||
|
||||
data = new int[initialCapacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link IntList} with a copy of the elements of
|
||||
* {@code intList}.
|
||||
* Create a new {@link IntList} with a copy of the elements of {@code intList}.
|
||||
*
|
||||
* @param intList
|
||||
* the list to copy
|
||||
@@ -172,9 +177,8 @@ public class IntList {
|
||||
* @param length
|
||||
* number of elements to remove
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code from} or {@code length} is negative, or if the
|
||||
* range defined by {@code from} and {@code length} is out of
|
||||
* bounds
|
||||
* if {@code from} or {@code length} is negative, or if the range
|
||||
* defined by {@code from} and {@code length} is out of bounds
|
||||
*/
|
||||
public void remove(final int from, final int length) {
|
||||
|
||||
@@ -221,9 +225,8 @@ public class IntList {
|
||||
* number of elements
|
||||
* @return the {@code length} elements starting at {@code from}
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code from} or {@code length} is negative, or if the
|
||||
* range defined by {@code from} and {@code length} is out of
|
||||
* bounds
|
||||
* if {@code from} or {@code length} is negative, or if the range
|
||||
* defined by {@code from} and {@code length} is out of bounds
|
||||
*/
|
||||
public int[] get(final int from, final int length) {
|
||||
if (from < 0) {
|
||||
@@ -260,12 +263,17 @@ public class IntList {
|
||||
private void ensureCapacity(final int newElements) {
|
||||
|
||||
final int requiredCapacity = index + newElements;
|
||||
if (requiredCapacity - 1 >= data.length) {
|
||||
final int newCapacity = data.length * 2 > requiredCapacity ? data.length * 2 : requiredCapacity;
|
||||
if (requiredCapacity < 0 || requiredCapacity > MAX_ARRAY_SIZE) {
|
||||
// overflow, or too big
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
if (requiredCapacity > data.length) {
|
||||
|
||||
final int[] newData = new int[newCapacity];
|
||||
System.arraycopy(data, 0, newData, 0, index);
|
||||
data = newData;
|
||||
int newCapacity = data.length + data.length / 2;
|
||||
newCapacity = Math.max(requiredCapacity, newCapacity);
|
||||
newCapacity = Math.min(MAX_ARRAY_SIZE, newCapacity);
|
||||
|
||||
data = Arrays.copyOf(data, newCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user