diff --git a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java index 4662f5d..7df8898 100644 --- a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java +++ b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java @@ -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); } }