diff --git a/src/main/java/com/reandroid/utils/collection/ArrayCollection.java b/src/main/java/com/reandroid/utils/collection/ArrayCollection.java index 558adb0a3..b7ec5f44b 100644 --- a/src/main/java/com/reandroid/utils/collection/ArrayCollection.java +++ b/src/main/java/com/reandroid/utils/collection/ArrayCollection.java @@ -1026,7 +1026,12 @@ private void slideLeft(int position, int amount){ private void slideRight(int position, int amount){ boolean locked = mLocked; this.mLocked = true; - ensureCapacity(amount); + if(availableCapacity() < amount){ + // Grow by the usual step rather than by exactly 'amount', otherwise + // inserting n items one by one reallocates and copies the array n times + int grow = calculateGrow(); + ensureCapacity(grow > amount ? grow : amount); + } Object[] elements = this.mElements; int size = this.size; int i = size - 1; @@ -1095,9 +1100,10 @@ public void ensureCapacity(int capacity) { return; } int size = this.size; - int length = size + capacity; - Object[] update = getNewArray(length); Object[] elements = this.mElements; + // 'capacity' is what is still missing on top of the free slots + int length = elements.length + capacity; + Object[] update = getNewArray(length); if(elements.length == 0 || size == 0){ this.mElements = update; return; diff --git a/src/test/java/com/reandroid/utils/collection/ArrayCollectionTest.java b/src/test/java/com/reandroid/utils/collection/ArrayCollectionTest.java new file mode 100644 index 000000000..75649e6f7 --- /dev/null +++ b/src/test/java/com/reandroid/utils/collection/ArrayCollectionTest.java @@ -0,0 +1,35 @@ +package com.reandroid.utils.collection; + +import org.junit.Assert; +import org.junit.Test; + +public class ArrayCollectionTest { + + @Test + public void testInsertAtIndexThenSetSize() { + ArrayCollection collection = new ArrayCollection<>(); + for (int i = 0; i < 1000; i++) { + collection.add(i / 2, i); + } + Assert.assertEquals(1000, collection.size()); + // insertions leave spare capacity behind, growing must still fit + collection.setSize(1500); + Assert.assertEquals(1500, collection.size()); + collection.ensureCapacity(10); + Assert.assertTrue(collection.availableCapacity() >= 10); + int free = collection.availableCapacity(); + collection.ensureCapacity(free + 5); + Assert.assertTrue(collection.availableCapacity() >= free + 5); + } + + @Test + public void testInsertOrder() { + ArrayCollection collection = new ArrayCollection<>(); + for (int i = 0; i < 100; i++) { + collection.add(0, i); + } + for (int i = 0; i < 100; i++) { + Assert.assertEquals(Integer.valueOf(99 - i), collection.get(i)); + } + } +}