diff --git a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java index b9c99d1..3f54ae8 100644 --- a/primitiveCollections/src/main/java/org/lucares/collections/IntList.java +++ b/primitiveCollections/src/main/java/org/lucares/collections/IntList.java @@ -20,7 +20,7 @@ public final class IntList implements Serializable, Cloneable { // TODO support sublists // TODO add lastIndexOf // TODO remove bounds checks that are handled by java, e.g. negative indices - // TODO clear + // TODO intersection for unsorted lists private static final long serialVersionUID = 2622570032686034909L; @@ -367,6 +367,7 @@ public final class IntList implements Serializable, Cloneable { * @see #trim() */ public void retainAll(final IntList retain) { + int insertPosition = 0; for (int i = 0; i < size; i++) { final int current = data[i]; @@ -702,4 +703,47 @@ public final class IntList implements Serializable, Cloneable { } } + /** + * Returns a list with all elements that are in {@code a} and {@code b}. + *

+ * The cardinality of each element will be equal to the minimum of the + * cardinality of each element in the given lists. + * + * @param a + * a sorted {@link IntList} + * @param b + * a sorted {@link IntList} + * @return {@link IntList} containing all elements that are in {@code a} and + * {@code b} + * @throws NullPointerException + * if {@code a} or {@code b} is null + */ + public static IntList intersection(final IntList a, final IntList b) { + final IntList result = new IntList(Math.min(a.size(), b.size())); + + if (a.isSorted() && b.isSorted()) { + int l = 0; + int r = 0; + + while (l < a.size() && r < b.size()) { + + final int lv = a.get(l); + final int rv = b.get(r); + + if (lv < rv) { + l++; + } else if (lv > rv) { + r++; + } else { + result.add(lv); + l++; + r++; + } + } + } else { + throw new UnsupportedOperationException("retainAll on unsorted lists is not yet supported"); + } + return result; + } + } diff --git a/primitiveCollections/src/test/java/org/lucares/collections/IntListTest.java b/primitiveCollections/src/test/java/org/lucares/collections/IntListTest.java index c6f502a..ea8637a 100644 --- a/primitiveCollections/src/test/java/org/lucares/collections/IntListTest.java +++ b/primitiveCollections/src/test/java/org/lucares/collections/IntListTest.java @@ -1032,4 +1032,31 @@ public class IntListTest { list.replaceAll(v -> 2); // replace all with 2 -> [2,2,2,2] Assert.assertFalse("unsorted list stays unsorted", list.isSorted()); } + + @Test + public void testIntersectionSortedLists() { + { + final IntList a = IntList.of(0, 1, 2, 3, 4); + final IntList b = IntList.of(2, 4, 5); + final IntList actual = IntList.intersection(a, b); + Assert.assertEquals(IntList.of(2, 4), actual); + } + + /* + * cardinality of elements that occur multiple time is equal to the minimum + * cardinality in either list + */ + { + final IntList a = IntList.of(3, 3, 3); + final IntList b = IntList.of(3, 3); + final IntList actual = IntList.intersection(a, b); + Assert.assertEquals(IntList.of(3, 3), actual); + } + { + final IntList a = IntList.of(4); + final IntList b = IntList.of(4, 4, 4); + final IntList actual = IntList.intersection(a, b); + Assert.assertEquals(IntList.of(4), actual); + } + } }