diff --git a/CHANGES.txt b/CHANGES.txt index 031f8377..43ba631f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,6 +3,8 @@ ** New features and API changes + GH-247: Add KTypeArrayList removeAt and rename remove to removeElement. (Bruno Roustant) + GH-244: Hide RamUsageEstimator from the public API. (Dawid Weiss) GH-239: Minimum Java bumped to 11 (from 8). (Dawid Weiss) diff --git a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayList.java b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayList.java index a5263112..5895a256 100644 --- a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayList.java +++ b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayList.java @@ -218,15 +218,28 @@ public KType set(int index, KType e1) { * {@inheritDoc} */ @Override - public KType remove(int index) { + public KType removeAt(int index) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ")."; final KType v = Intrinsics. cast(buffer[index]); - if (index + 1 < elementsCount) { - System.arraycopy(buffer, index + 1, buffer, index, elementsCount - index - 1); - } - elementsCount--; + System.arraycopy(buffer, index + 1, buffer, index, --elementsCount - index); + /* #if ($TemplateOptions.KTypeGeneric) */ + buffer[elementsCount] = Intrinsics.empty(); + /* #end */ + return v; + } + + /** + * {@inheritDoc} + */ + @Override + public KType removeLast() { + assert elementsCount > 0; + + final KType v = Intrinsics. cast(buffer[--elementsCount]); + /* #if ($TemplateOptions.KTypeGeneric) */ buffer[elementsCount] = Intrinsics.empty(); + /* #end */ return v; } @@ -245,7 +258,17 @@ public void removeRange(int fromIndex, int toIndex) { System.arraycopy(buffer, toIndex, buffer, fromIndex, elementsCount - toIndex); final int count = toIndex - fromIndex; elementsCount -= count; + /* #if ($TemplateOptions.KTypeGeneric) */ Arrays.fill(buffer, elementsCount, elementsCount + count, Intrinsics.empty()); + /* #end */ + } + + /** + * {@inheritDoc} + */ + @Override + public boolean removeElement(KType e1) { + return removeFirst(e1) != -1; } /** @@ -255,7 +278,7 @@ public void removeRange(int fromIndex, int toIndex) { public int removeFirst(KType e1) { final int index = indexOf(e1); if (index >= 0) - remove(index); + removeAt(index); return index; } @@ -266,7 +289,7 @@ public int removeFirst(KType e1) { public int removeLast(KType e1) { final int index = lastIndexOf(e1); if (index >= 0) - remove(index); + removeAt(index); return index; } @@ -278,19 +301,18 @@ public int removeAll(KType e1) { int to = 0; for (int from = 0; from < elementsCount; from++) { if (Intrinsics.equals(this, e1, buffer[from])) { - buffer[from] = Intrinsics.empty(); continue; } - if (to != from) { buffer[to] = buffer[from]; - buffer[from] = Intrinsics.empty(); } to++; } - final int deleted = elementsCount - to; this.elementsCount = to; + /* #if ($TemplateOptions.KTypeGeneric) */ + Arrays.fill(buffer, elementsCount, elementsCount + deleted, Intrinsics.empty()); + /* #end */ return deleted; } diff --git a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeIndexedContainer.java b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeIndexedContainer.java index 1437b40b..32aa8adf 100644 --- a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeIndexedContainer.java +++ b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeIndexedContainer.java @@ -8,6 +8,12 @@ */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeIndexedContainer extends KTypeCollection, RandomAccess { + /** + * Removes the first element that equals e1, returning whether + * an element has been removed. + */ + public boolean removeElement(KType e1); + /** * Removes the first element that equals e1, returning its * deleted position or -1 if the element was not found. @@ -68,7 +74,13 @@ public interface KTypeIndexedContainer extends KTypeCollection, Ra * @see #removeLast * @see #removeAll */ - public KType remove(int index); + public KType removeAt(int index); + + /** + * Removes and returns the last element of this container. + * This container must not be empty. + */ + public KType removeLast(); /** * Removes from this container all of the elements with indexes between diff --git a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeStack.java b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeStack.java index 9198f613..14cccfdc 100644 --- a/hppc/src/main/templates/com/carrotsearch/hppc/KTypeStack.java +++ b/hppc/src/main/templates/com/carrotsearch/hppc/KTypeStack.java @@ -156,13 +156,7 @@ public void discard() { * Remove the top element from the stack and return it. */ public KType pop() { - assert elementsCount > 0; - - final KType v = Intrinsics. cast(buffer[--elementsCount]); - /* #if ($TemplateOptions.KTypeGeneric) */ - buffer[elementsCount] = null; - /* #end */ - return v; + return removeLast(); } /** diff --git a/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayListTest.java b/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayListTest.java index 84f19904..ce736114 100644 --- a/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayListTest.java +++ b/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayListTest.java @@ -34,6 +34,7 @@ public void initialize() list = new KTypeArrayList<>(); } + /*! #if ($TemplateOptions.KTypeGeneric) !*/ @After public void checkTrailingSpaceUninitialized() { @@ -43,6 +44,7 @@ public void checkTrailingSpaceUninitialized() assertTrue(Intrinsics. empty() == list.buffer[i]); } } + /*! #end !*/ /* */ @Test @@ -125,17 +127,34 @@ public void testSet() /* */ @Test - public void testRemove() + public void testRemoveAt() { list.add(asArray(0, 1, 2, 3, 4)); - list.remove(0); - list.remove(2); - list.remove(1); + list.removeAt(0); + list.removeAt(2); + list.removeAt(1); assertListEquals(list.toArray(), 1, 4); } + /* */ + @Test + public void testRemoveLast() { + list.add(asArray(0, 1, 2, 3, 4)); + + assertEquals2(4, list.removeLast()); + assertEquals2(4, list.size()); + assertListEquals(list.toArray(), 0, 1, 2, 3); + assertEquals2(3, list.removeLast()); + assertEquals2(3, list.size()); + assertListEquals(list.toArray(), 0, 1, 2); + assertEquals2(2, list.removeLast()); + assertEquals2(1, list.removeLast()); + assertEquals2(0, list.removeLast()); + assertTrue(list.isEmpty()); + } + /* */ @Test public void testRemoveRange() @@ -173,17 +192,16 @@ public void testRemoveFirstLast() assertListEquals(list.toArray(), 2, 1); assertEquals(-1, list.removeLast(k0)); - /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.clear(); - list.add(newArray(k0, null, k2, null, k0)); - assertEquals(1, list.removeFirst(null)); - assertEquals(2, list.removeLast(null)); - assertListEquals(list.toArray(), 0, 2, 0); - /*! #end !*/ + list.add(newArray(k1, Intrinsics.empty(), k2, Intrinsics.empty(), k1)); + assertEquals(1, list.removeFirst(Intrinsics.empty())); + assertEquals(2, list.removeLast(Intrinsics.empty())); + assertListEquals(list.toArray(), 1, 2, 1); } /* */ @Test + @SuppressWarnings("unchecked") public void testRemoveAll() { list.add(asArray(0, 1, 0, 1, 0)); @@ -195,13 +213,11 @@ public void testRemoveAll() assertEquals(2, list.removeAll(k1)); assertTrue(list.isEmpty()); - /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.clear(); - list.add(newArray(k0, null, k2, null, k0)); - assertEquals(2, list.removeAll((KType) null)); - assertEquals(0, list.removeAll((KType) null)); - assertListEquals(list.toArray(), 0, 2, 0); - /*! #end !*/ + list.add(newArray(k1, Intrinsics.empty(), k2, Intrinsics.empty(), k1)); + assertEquals(2, list.removeAll((KType) Intrinsics.empty())); + assertEquals(0, list.removeAll((KType) Intrinsics.empty())); + assertListEquals(list.toArray(), 1, 2, 1); } /*! #if (not $TemplateOptions.isKTypeAnyOf("DOUBLE", "FLOAT", "BYTE")) !*/ @@ -286,33 +302,31 @@ public boolean apply(KType v) /* */ @Test + @SuppressWarnings("unchecked") public void testIndexOf() { - list.add(asArray(0, 1, 2, 1, 0)); + list.add(asArray(3, 1, 2, 1, 3)); - /*! #if ($TemplateOptions.KTypeGeneric) !*/ - list.add((KType) null); - assertEquals(5, list.indexOf(null)); - /*! #end !*/ + list.add((KType) Intrinsics.empty()); + assertEquals(5, list.indexOf(Intrinsics.empty())); - assertEquals(0, list.indexOf(k0)); - assertEquals(-1, list.indexOf(k3)); + assertEquals(0, list.indexOf(k3)); + assertEquals(-1, list.indexOf(k4)); assertEquals(2, list.indexOf(k2)); } - + /* */ @Test + @SuppressWarnings("unchecked") public void testLastIndexOf() { - list.add(asArray(0, 1, 2, 1, 0)); + list.add(asArray(3, 1, 2, 1, 3)); - /*! #if ($TemplateOptions.KTypeGeneric) !*/ - list.add((KType) null); - assertEquals(5, list.lastIndexOf(null)); - /*! #end !*/ + list.add((KType) Intrinsics.empty()); + assertEquals(5, list.lastIndexOf(Intrinsics.empty())); - assertEquals2(4, list.lastIndexOf(k0)); - assertEquals2(-1, list.lastIndexOf(k3)); + assertEquals2(4, list.lastIndexOf(k3)); + assertEquals2(-1, list.lastIndexOf(k4)); assertEquals2(2, list.lastIndexOf(k2)); } @@ -487,7 +501,8 @@ public void testClear() { list.add(asArray( 1, 2, 3)); list.clear(); - checkTrailingSpaceUninitialized(); + assertTrue(list.isEmpty()); + assertEquals(-1, list.indexOf(cast(1))); } /* */ @@ -539,17 +554,15 @@ public void testEqualElements() assertTrue(l2.equalElements(l1)); } - /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test - public void testHashCodeWithNulls() + public void testHashCodeWithEmptyKeys() { - KTypeArrayList l1 = KTypeArrayList.from(k1, null, k3); - KTypeArrayList l2 = KTypeArrayList.from(k1, null, k3); + KTypeArrayList l1 = KTypeArrayList.from(k1, Intrinsics.empty(), k3); + KTypeArrayList l2 = KTypeArrayList.from(k1, Intrinsics.empty(), k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } - /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test @@ -561,10 +574,10 @@ class A { class B extends A { } - KTypeArrayList list2 = new KTypeArrayList(); + KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(new B()); - KTypeArrayList list3 = new KTypeArrayList(); + KTypeArrayList list3 = new KTypeArrayList<>(); list3.add(new B()); list3.add(new A()); list3.addAll(list2);