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;
|
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[] data;
|
||||||
|
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
@@ -33,16 +38,16 @@ public class IntList {
|
|||||||
* if initial capacity is negative
|
* if initial capacity is negative
|
||||||
*/
|
*/
|
||||||
public IntList(final int initialCapacity) {
|
public IntList(final int initialCapacity) {
|
||||||
if (initialCapacity < 0) {
|
if (initialCapacity < 0 || initialCapacity > MAX_ARRAY_SIZE) {
|
||||||
throw new IllegalArgumentException("initial capacity must not be negative");
|
throw new IllegalArgumentException(
|
||||||
|
"initial capacity must not be negative and not larger than " + MAX_ARRAY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = new int[initialCapacity];
|
data = new int[initialCapacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link IntList} with a copy of the elements of
|
* Create a new {@link IntList} with a copy of the elements of {@code intList}.
|
||||||
* {@code intList}.
|
|
||||||
*
|
*
|
||||||
* @param intList
|
* @param intList
|
||||||
* the list to copy
|
* the list to copy
|
||||||
@@ -172,9 +177,8 @@ public class IntList {
|
|||||||
* @param length
|
* @param length
|
||||||
* number of elements to remove
|
* number of elements to remove
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException
|
||||||
* if {@code from} or {@code length} is negative, or if the
|
* if {@code from} or {@code length} is negative, or if the range
|
||||||
* range defined by {@code from} and {@code length} is out of
|
* defined by {@code from} and {@code length} is out of bounds
|
||||||
* bounds
|
|
||||||
*/
|
*/
|
||||||
public void remove(final int from, final int length) {
|
public void remove(final int from, final int length) {
|
||||||
|
|
||||||
@@ -221,9 +225,8 @@ public class IntList {
|
|||||||
* number of elements
|
* number of elements
|
||||||
* @return the {@code length} elements starting at {@code from}
|
* @return the {@code length} elements starting at {@code from}
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException
|
||||||
* if {@code from} or {@code length} is negative, or if the
|
* if {@code from} or {@code length} is negative, or if the range
|
||||||
* range defined by {@code from} and {@code length} is out of
|
* defined by {@code from} and {@code length} is out of bounds
|
||||||
* bounds
|
|
||||||
*/
|
*/
|
||||||
public int[] get(final int from, final int length) {
|
public int[] get(final int from, final int length) {
|
||||||
if (from < 0) {
|
if (from < 0) {
|
||||||
@@ -260,12 +263,17 @@ public class IntList {
|
|||||||
private void ensureCapacity(final int newElements) {
|
private void ensureCapacity(final int newElements) {
|
||||||
|
|
||||||
final int requiredCapacity = index + newElements;
|
final int requiredCapacity = index + newElements;
|
||||||
if (requiredCapacity - 1 >= data.length) {
|
if (requiredCapacity < 0 || requiredCapacity > MAX_ARRAY_SIZE) {
|
||||||
final int newCapacity = data.length * 2 > requiredCapacity ? data.length * 2 : requiredCapacity;
|
// overflow, or too big
|
||||||
|
throw new OutOfMemoryError();
|
||||||
|
}
|
||||||
|
if (requiredCapacity > data.length) {
|
||||||
|
|
||||||
final int[] newData = new int[newCapacity];
|
int newCapacity = data.length + data.length / 2;
|
||||||
System.arraycopy(data, 0, newData, 0, index);
|
newCapacity = Math.max(requiredCapacity, newCapacity);
|
||||||
data = newData;
|
newCapacity = Math.min(MAX_ARRAY_SIZE, newCapacity);
|
||||||
|
|
||||||
|
data = Arrays.copyOf(data, newCapacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user