From 91e76c85dc4a9e7ff38c64af9af293f2770d0a3a Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 00:56:46 +0530 Subject: [PATCH 01/24] Add findDuplicates method to ListUtils with comprehensive test cases --- .../commons/collections4/ListUtils.java | 34 +++++++++++++ .../commons/collections4/ListUtilsTest.java | 48 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index 04744234ac..6a8197a0a6 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.Set; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.functors.DefaultEquator; @@ -173,6 +174,39 @@ public static List fixedSizeList(final List list) { return FixedSizeList.fixedSizeList(list); } + /** + * Finds and returns a list of duplicate elements in the given list. + *

+ * This method uses two sets: one for tracking seen elements and one for + * collecting duplicates. It iterates through the list once and collects + * duplicates in a result list. + *

+ * + * @param the type of elements in the list + * @param list the list to check for duplicates, must not be null + * @return a list of duplicate elements, or an empty list if no duplicates are found + * @throws NullPointerException if the list is null + */ + public static List findDuplicates(final List list) { + if (list == null) { + throw new NullPointerException("The input list must not be null."); + } + + Set seen = new HashSet<>(); + Set duplicates = new HashSet<>(); + List result = new ArrayList<>(); + + for (E element : list) { + if (!seen.add(element)) { + if (duplicates.add(element)) { + result.add(element); + } + } + } + + return result; + } + /** * Gets the first element of a list. *

diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 8d232cb4aa..6ed37924f8 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -102,6 +102,54 @@ public void testEquals() { assertFalse(ListUtils.isEqualList(list1, list2)); } + @Test + public void testFindDuplicatesWithDuplicates() { + List input = Arrays.asList(1, 2, 3, 2, 4, 5, 3); + List expected = Arrays.asList(2, 3); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should contain only the duplicate elements."); + } + + @Test + public void testFindDuplicatesNoDuplicates() { + List input = Arrays.asList(1, 2, 3, 4, 5); + List expected = Arrays.asList(); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should be empty as there are no duplicates."); + } + + @Test + public void testFindDuplicatesEmptyList() { + List input = Arrays.asList(); + List expected = Arrays.asList(); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should be empty as the input list is empty."); + } + + @Test + public void testFindDuplicatesSingleElement() { + List input = Arrays.asList(1); + List expected = Arrays.asList(); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should be empty as there is only one element."); + } + + @Test + public void testFindDuplicatesMultipleDuplicates() { + List input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4); + List expected = Arrays.asList(1, 2, 3, 4); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should contain all duplicate elements."); + } + + @Test + public void testFindDuplicatesAllSameElements() { + List input = Arrays.asList(5, 5, 5, 5); + List expected = Arrays.asList(5); + List actual = ListUtils.findDuplicates(input); + assertEquals(expected, actual, "The list should contain the single element as all elements are the same."); + } + @Test public void testGetFirst() { assertEquals(a, ListUtils.getFirst(fullList)); From e12fc22b11d1d2c6a967566a41a25ac14dd144e2 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 14:24:51 +0000 Subject: [PATCH 02/24] findDuplicates --- src/main/java/org/apache/commons/collections4/ListUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index 6a8197a0a6..fd50c05267 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -186,11 +186,10 @@ public static List fixedSizeList(final List list) { * @param list the list to check for duplicates, must not be null * @return a list of duplicate elements, or an empty list if no duplicates are found * @throws NullPointerException if the list is null + * @since 4.5.0-M3 */ public static List findDuplicates(final List list) { - if (list == null) { - throw new NullPointerException("The input list must not be null."); - } + Objects.requireNonNull(list, "The input list must not be null."); Set seen = new HashSet<>(); Set duplicates = new HashSet<>(); From 53c385da09d77e498fdd082f82cf8a8f78a16de2 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 14:38:44 +0000 Subject: [PATCH 03/24] updated tests --- .../org/apache/commons/collections4/ListUtilsTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 6ed37924f8..695b4af2fc 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -121,19 +121,16 @@ public void testFindDuplicatesNoDuplicates() { @Test public void testFindDuplicatesEmptyList() { List input = Arrays.asList(); - List expected = Arrays.asList(); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should be empty as the input list is empty."); + assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as the input list is empty."); } @Test public void testFindDuplicatesSingleElement() { List input = Arrays.asList(1); - List expected = Arrays.asList(); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should be empty as there is only one element."); + assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as there is only one element."); } + @Test public void testFindDuplicatesMultipleDuplicates() { List input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4); From 8a2808ad09970c61b63274e3e5af8bad93e8db7f Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 20:22:01 +0530 Subject: [PATCH 04/24] Update tests --- .../java/org/apache/commons/collections4/ListUtilsTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 695b4af2fc..3e9922abbe 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -113,9 +113,7 @@ public void testFindDuplicatesWithDuplicates() { @Test public void testFindDuplicatesNoDuplicates() { List input = Arrays.asList(1, 2, 3, 4, 5); - List expected = Arrays.asList(); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should be empty as there are no duplicates."); + assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as the input list has no duplicates."); } @Test From c455e6aa0a2afaab773ded70141dd0a6b6a5d88b Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:45:48 +0530 Subject: [PATCH 05/24] Add findDuplicates --- .../java/org/apache/commons/collections4/ListUtils.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index fd50c05267..b3dd237060 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -196,10 +196,8 @@ public static List findDuplicates(final List list) { List result = new ArrayList<>(); for (E element : list) { - if (!seen.add(element)) { - if (duplicates.add(element)) { - result.add(element); - } + if (!seen.add(element) && duplicates.add(element)) { + result.add(element); } } From 6ebffeb8f7df78e7b9467f65176c4570ffcf361d Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:43:32 +0530 Subject: [PATCH 06/24] Add findDuplicates --- .../apache/commons/collections4/ListUtils.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index b3dd237060..ff19fc8876 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -24,7 +24,6 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.Set; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.functors.DefaultEquator; @@ -189,19 +188,7 @@ public static List fixedSizeList(final List list) { * @since 4.5.0-M3 */ public static List findDuplicates(final List list) { - Objects.requireNonNull(list, "The input list must not be null."); - - Set seen = new HashSet<>(); - Set duplicates = new HashSet<>(); - List result = new ArrayList<>(); - - for (E element : list) { - if (!seen.add(element) && duplicates.add(element)) { - result.add(element); - } - } - - return result; + return CollectionUtils.duplicateList(list); } /** From 9197ae3be807157c51c725d0cf0b596efdf644ad Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:45:48 +0530 Subject: [PATCH 07/24] Add findDuplicates --- .../java/org/apache/commons/collections4/ListUtils.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index fd50c05267..b3dd237060 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -196,10 +196,8 @@ public static List findDuplicates(final List list) { List result = new ArrayList<>(); for (E element : list) { - if (!seen.add(element)) { - if (duplicates.add(element)) { - result.add(element); - } + if (!seen.add(element) && duplicates.add(element)) { + result.add(element); } } From 57e86e3ec201896aa3e1d20402e943cb9f4541e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Sep 2024 17:39:16 +0000 Subject: [PATCH 08/24] Bump org.easymock:easymock from 5.3.0 to 5.4.0 Bumps [org.easymock:easymock](https://github.com/easymock/easymock) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/easymock/easymock/releases) - [Changelog](https://github.com/easymock/easymock/blob/master/ReleaseNotes.md) - [Commits](https://github.com/easymock/easymock/compare/easymock-5.3.0...easymock-5.4.0) --- updated-dependencies: - dependency-name: org.easymock:easymock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9188ff796b..de218655d1 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ org.easymock easymock - 5.3.0 + 5.4.0 test From a465792ca3e30aac585049579a29e2f4740bd915 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 16:01:10 -0400 Subject: [PATCH 09/24] Bump org.easymock:easymock from 5.3.0 to 5.4.0 #521 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 9abcc6b303..a95400ec7b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -48,6 +48,7 @@ Bump org.hamcrest:hamcrest from 2.2 to 3.0 #522, #532. Bump com.google.guava:guava-testlib from 33.2.1-jre to 33.3.0-jre #531. Bump MathJax from 2.7.2 to 2.7.9. + Bump org.easymock:easymock from 5.3.0 to 5.4.0 #521. From 2081cbe0c5b7d4e8ef377e8d079c9df68c7a2feb Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 16:07:49 -0400 Subject: [PATCH 10/24] Whitespace --- .../org/apache/commons/collections4/bag/AbstractMapBag.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java index e9f2bfe84f..f4be8902a0 100644 --- a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java @@ -109,10 +109,12 @@ public void remove() { canRemove = false; } } + /** * Mutable integer class for storing the data. */ protected static class MutableInteger { + /** The value of this mutable. */ protected int value; @@ -137,8 +139,10 @@ public int hashCode() { return value; } } + /** The map to use to store the data */ private transient Map map; + /** The current total size of the bag */ private int size; From ff20df624d58cbf4e7e1e1ffb84e89d13fcc230e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 16:12:14 -0400 Subject: [PATCH 11/24] Use Java 8's Map.getOrDefault() Javadoc --- .../commons/collections4/CollectionUtils.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/src/main/java/org/apache/commons/collections4/CollectionUtils.java index cf7d7c984b..b5feffd720 100644 --- a/src/main/java/org/apache/commons/collections4/CollectionUtils.java +++ b/src/main/java/org/apache/commons/collections4/CollectionUtils.java @@ -63,6 +63,8 @@ public class CollectionUtils { */ private static class CardinalityHelper { + private static final Integer ZERO = Integer.valueOf(0); + /** Contains the cardinality for each object in collection A. */ final Map cardinalityA; @@ -81,28 +83,26 @@ private static class CardinalityHelper { /** * Returns the frequency of this object in collection A. - * @param obj the object + * + * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection A */ - public int freqA(final Object obj) { - return getFreq(obj, cardinalityA); + public int freqA(final Object key) { + return getFreq(key, cardinalityA); } /** * Returns the frequency of this object in collection B. - * @param obj the object + * + * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection B */ - public int freqB(final Object obj) { - return getFreq(obj, cardinalityB); + public int freqB(final Object key) { + return getFreq(key, cardinalityB); } - private int getFreq(final Object obj, final Map freqMap) { - final Integer count = freqMap.get(obj); - if (count != null) { - return count.intValue(); - } - return 0; + private int getFreq(final Object key, final Map freqMap) { + return freqMap.getOrDefault(key, ZERO).intValue(); } /** From 2adf5ee721dbc7ed9abaed5902f8ca2693442fc7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 17:18:05 -0400 Subject: [PATCH 12/24] Reimplement the package-private CollectionUtils.CardinalityHelper using Bags instead of custom Maps --- .../commons/collections4/CollectionUtils.java | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/src/main/java/org/apache/commons/collections4/CollectionUtils.java index b5feffd720..ff53f36dca 100644 --- a/src/main/java/org/apache/commons/collections4/CollectionUtils.java +++ b/src/main/java/org/apache/commons/collections4/CollectionUtils.java @@ -63,26 +63,29 @@ public class CollectionUtils { */ private static class CardinalityHelper { - private static final Integer ZERO = Integer.valueOf(0); + static boolean equals(final Collection a, final Collection b) { + return new HashBag<>(a).equals(new HashBag<>(b)); + } /** Contains the cardinality for each object in collection A. */ - final Map cardinalityA; + final Bag cardinalityA; /** Contains the cardinality for each object in collection B. */ - final Map cardinalityB; + final Bag cardinalityB; /** - * Create a new CardinalityHelper for two collections. + * Creates a new CardinalityHelper for two collections. + * * @param a the first collection * @param b the second collection */ CardinalityHelper(final Iterable a, final Iterable b) { - cardinalityA = getCardinalityMap(a); - cardinalityB = getCardinalityMap(b); + cardinalityA = new HashBag<>(a); + cardinalityB = new HashBag<>(b); } /** - * Returns the frequency of this object in collection A. + * Gets the frequency of this object in collection A. * * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection A @@ -92,7 +95,7 @@ public int freqA(final Object key) { } /** - * Returns the frequency of this object in collection B. + * Gets the frequency of this object in collection B. * * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection B @@ -101,12 +104,13 @@ public int freqB(final Object key) { return getFreq(key, cardinalityB); } - private int getFreq(final Object key, final Map freqMap) { - return freqMap.getOrDefault(key, ZERO).intValue(); + private int getFreq(final Object key, final Bag freqMap) { + return freqMap.getCount(key); } /** - * Returns the maximum frequency of an object. + * Gets the maximum frequency of an object. + * * @param obj the object * @return the maximum frequency of the object */ @@ -115,7 +119,8 @@ public final int max(final Object obj) { } /** - * Returns the minimum frequency of an object. + * Gets the minimum frequency of an object. + * * @param obj the object * @return the minimum frequency of the object */ @@ -1257,21 +1262,7 @@ public static boolean isEmpty(final Collection coll) { * @throws NullPointerException if either collection is null */ public static boolean isEqualCollection(final Collection a, final Collection b) { - Objects.requireNonNull(a, "a"); - Objects.requireNonNull(b, "b"); - if (a.size() != b.size()) { - return false; - } - final CardinalityHelper helper = new CardinalityHelper<>(a, b); - if (helper.cardinalityA.size() != helper.cardinalityB.size()) { - return false; - } - for (final Object obj : helper.cardinalityA.keySet()) { - if (helper.freqA(obj) != helper.freqB(obj)) { - return false; - } - } - return true; + return CardinalityHelper.equals(a, b); } /** From 40dc0aae503d852bd11083ebb35a6d2e961cd2af Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 17:24:20 -0400 Subject: [PATCH 13/24] Add HashBag.HashBag(Iterable) - Add TreeBag.TreeBag(Iterable) --- src/changes/changes.xml | 2 ++ .../collections4/bag/AbstractMapBag.java | 15 ++++++++++++++- .../commons/collections4/bag/HashBag.java | 18 ++++++++++++++---- .../commons/collections4/bag/TreeBag.java | 10 ++++++++++ .../multimap/AbstractMultiValuedMapTest.java | 14 +++++++++++++- 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a95400ec7b..aa9767bbef 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -40,6 +40,8 @@ Add CollectionUtils.duplicateList(Collection). Add CollectionUtils.duplicateSet(Collection). Add CollectionUtils.duplicateSequencedSet(Collection). + Add HashBag.HashBag(Iterable). + Add TreeBag.TreeBag(Iterable). Update bloom filter documentation #508. Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514. diff --git a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java index f4be8902a0..d3fa5e6e1e 100644 --- a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import org.apache.commons.collections4.Bag; @@ -165,7 +166,19 @@ protected AbstractMapBag() { * @param map the map to assign */ protected AbstractMapBag(final Map map) { - this.map = map; + this.map = Objects.requireNonNull(map, "map"); + } + + /** + * Constructs a new instance that assigns the specified Map as the backing store. The map + * must be empty and non-null. The bag is filled from the iterable elements. + * + * @param map the map to assign. + * @param iterable The bag is filled from these iterable elements. + */ + protected AbstractMapBag(final Map map, final Iterable iterable) { + this(map); + iterable.forEach(this::add); } /** diff --git a/src/main/java/org/apache/commons/collections4/bag/HashBag.java b/src/main/java/org/apache/commons/collections4/bag/HashBag.java index 1335669aa1..6b33ab8b7f 100644 --- a/src/main/java/org/apache/commons/collections4/bag/HashBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/HashBag.java @@ -50,13 +50,23 @@ public HashBag() { } /** - * Constructs a bag containing all the members of the given collection. + * Constructs a bag containing all the members of the given Collection. * - * @param coll a collection to copy into this bag + * @param collection a collection to copy into this bag. */ - public HashBag(final Collection coll) { + public HashBag(final Collection collection) { this(); - addAll(coll); + addAll(collection); + } + + /** + * Constructs a bag containing all the members of the given Iterable. + * + * @param iterable an iterable to copy into this bag. + * @since 4.5.0-M3 + */ + public HashBag(final Iterable iterable) { + super(new HashMap<>(), iterable); } /** diff --git a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java index fa10f94db6..14f7a6802d 100644 --- a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java @@ -67,6 +67,16 @@ public TreeBag(final Collection coll) { addAll(coll); } + /** + * Constructs a bag containing all the members of the given Iterable. + * + * @param iterable an iterable to copy into this bag. + * @since 4.5.0-M3 + */ + public TreeBag(final Iterable iterable) { + super(new TreeMap<>(), iterable); + } + /** * Constructs an empty bag that maintains order on its unique representative * members according to the given {@link Comparator}. diff --git a/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java b/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java index ac80948e2e..b2905b98f1 100644 --- a/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java +++ b/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java @@ -931,7 +931,7 @@ public void testKeysBagContainsAll() { } @Test - public void testKeysBagIterator() { + public void testKeysBagIterator1() { final MultiValuedMap map = makeFullMap(); final Collection col = new ArrayList<>(map.keys()); final Bag bag = new HashBag<>(col); @@ -942,6 +942,18 @@ public void testKeysBagIterator() { assertEquals(getSampleTotalValueCount(), bag.size()); } + @Test + public void testKeysBagIterator2() { + final MultiValuedMap map = makeFullMap(); + final Iterable iterable = new ArrayList<>(map.keys()); + final Bag bag = new HashBag<>(iterable); + final int maxK = getSampleKeySize(); + for (int k = 0; k < maxK; k++) { + assertEquals(getSampleCountPerKey(), bag.getCount(makeKey(k))); + } + assertEquals(getSampleTotalValueCount(), bag.size()); + } + @Test public void testKeySetSize() { final MultiValuedMap map = makeFullMap(); From 94c51b3c77abe147f1ace9c69d5d4cd745f0fac7 Mon Sep 17 00:00:00 2001 From: Oleksii PELYKH Date: Tue, 25 Jun 2024 11:55:12 +0200 Subject: [PATCH 14/24] [COLLECTIONS-858] CartesianProductIterator --- .../iterators/CartesianProductIterator.java | 156 +++++++++++++ .../CartesianProductIteratorTest.java | 209 ++++++++++++++++++ 2 files changed, 365 insertions(+) create mode 100644 src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java create mode 100644 src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java diff --git a/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java new file mode 100644 index 0000000000..2aea039222 --- /dev/null +++ b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + +/** + * This iterator creates a Cartesian product of the input iterables, + * equivalent to nested for-loops. + *

+ * The iterables provided to the constructor are used in reverse order, each + * until exhaustion before proceeding to the next element of the prior iterable + * and repeating. Consider the following example: + * + *

{@code
+ * List iterable1 = Arrays.asList('A', 'B', 'C');
+ * List iterable2 = Arrays.asList('1', '2', '3');
+ * CartesianProductIterator it = new CartesianProductIterator<>(
+ *         iterable1,
+ *         iterable2);
+ * while (it.hasNext()) {
+ *     List tuple = it.next();
+ *     System.out.println(tuple.get(0) + ", " + tuple.get(1));
+ * }
+ * }
+ * + * The output will be: + * + *
+ * A, 1
+ * A, 2
+ * A, 3
+ * B, 1
+ * B, 2
+ * B, 3
+ * C, 1
+ * C, 2
+ * C, 3
+ * 
+ *

+ * The {@code remove()} operation is not supported, and will throw an + * {@code UnsupportedOperationException}. + *

+ * If any of the input iterables is empty, the Cartesian product will be empty. + * If any of the input iterables is infinite, the Cartesian product will be + * infinite. + * + * @param the type of the objects being permuted + * @since 4.5.0 + */ +public class CartesianProductIterator implements Iterator> { + + /** + * The iterables to create the Cartesian product from. + */ + private final List> iterables; + + /** + * The iterators to generate the Cartesian product tuple from. + */ + private final List> iterators; + + /** + * The previous generated tuple of elements. + */ + private List previousTuple; + + /** + * Constructs a new {@code CartesianProductIterator} instance with given iterables. + * + * @param iterables the iterables to create the Cartesian product from + * @throws NullPointerException if any of the iterables is null + */ + @SafeVarargs + public CartesianProductIterator(final Iterable... iterables) { + Objects.requireNonNull(iterables, "iterables"); + this.iterables = new ArrayList<>(iterables.length); + this.iterators = new ArrayList<>(iterables.length); + for (final Iterable iterable : iterables) { + Objects.requireNonNull(iterable, "iterable"); + this.iterables.add(iterable); + final Iterator iterator = iterable.iterator(); + if (!iterator.hasNext()) { + iterators.clear(); + break; + } + iterators.add(iterator); + } + } + + /** + * Returns {@code true} if the iteration has more elements. + * + * @return true if there are more tuples, otherwise false + */ + @Override + public boolean hasNext() { + return iterators.stream().anyMatch(Iterator::hasNext); + } + + /** + * Returns the next tuple of the input iterables. + * + * @return a list of the input iterables' elements + * @throws NoSuchElementException if there are no more tuples + */ + @Override + public List next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + if (previousTuple == null) { + previousTuple = new ArrayList<>(iterables.size()); + for (final Iterator iterator : iterators) { + previousTuple.add(iterator.next()); + } + return new ArrayList<>(previousTuple); + } + + for (int i = iterators.size() - 1; i >= 0; i--) { + Iterator iterator = iterators.get(i); + if (iterator.hasNext()) { + previousTuple.set(i, iterator.next()); + return new ArrayList<>(previousTuple); + } + iterator = iterables.get(i).iterator(); + iterators.set(i, iterator); + previousTuple.set(i, iterator.next()); + } + throw new IllegalStateException("reached unreachable code"); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); + } +} diff --git a/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java b/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java new file mode 100644 index 0000000000..b32eeb7267 --- /dev/null +++ b/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.collections4.iterators; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +/** + * Test class for {@link CartesianProductIterator}. + */ +public class CartesianProductIteratorTest extends AbstractIteratorTest> { + + private List letters; + private List numbers; + private List symbols; + private List emptyList; + + public CartesianProductIteratorTest() { + super(CartesianProductIteratorTest.class.getSimpleName()); + } + + @Override + public CartesianProductIterator makeEmptyIterator() { + return new CartesianProductIterator<>(); + } + + @Override + public CartesianProductIterator makeObject() { + return new CartesianProductIterator<>(letters, numbers, symbols); + } + + @BeforeEach + public void setUp() { + letters = Arrays.asList('A', 'B', 'C'); + numbers = Arrays.asList('1', '2', '3'); + symbols = Arrays.asList('!', '?'); + emptyList = Collections.emptyList(); + } + + @Override + public boolean supportsRemove() { + return false; + } + + @Test + public void testRemoveThrows() { + final CartesianProductIterator it = makeObject(); + assertThrows(UnsupportedOperationException.class, it::remove); + } + + @Test + public void testEmptyCollection() { + final CartesianProductIterator it = new CartesianProductIterator<>(letters, Collections.emptyList()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + /** + * test checking that all the tuples are returned + */ + @Test + public void testExhaustivity() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = makeObject(); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(18, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : numbers) { + for (final Character c : symbols) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } + + /** + * test checking that no tuples are returned when at least one of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, emptyList, symbols); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when first of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyFirstList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(emptyList, numbers, symbols); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when last of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyLastList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, numbers, emptyList); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when all the lists are empty + */ + @Test + public void testExhaustivityWithAllEmptyLists() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(emptyList, emptyList, emptyList); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that all tuples are returned when same list is passed multiple times + */ + @Test + public void testExhaustivityWithSameList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, letters, letters); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(27, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : letters) { + for (final Character c : letters) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } + + /** + * test that all tuples are provided to consumer + */ + @Test + public void testForEachRemaining() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = makeObject(); + it.forEachRemaining(tuple -> resultsList.add(tuple.toArray(new Character[0]))); + assertEquals(18, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : numbers) { + for (final Character c : symbols) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } +} From eb748a38fe62d5cb9e022d7739dbaaa83198a78c Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 17:48:44 -0400 Subject: [PATCH 15/24] Add CartesianProductIterator #509 --- src/changes/changes.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index aa9767bbef..2f20ba2244 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -42,10 +42,11 @@ Add CollectionUtils.duplicateSequencedSet(Collection). Add HashBag.HashBag(Iterable). Add TreeBag.TreeBag(Iterable). + Add CartesianProductIterator #509. - Update bloom filter documentation #508. - Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514. - Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 #516, #525, #535. + Update bloom filter documentation #508. + Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514. + Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 #516, #525, #535. Bump org.apache.commons:commons-parent from 71 to 74 #534. Bump org.hamcrest:hamcrest from 2.2 to 3.0 #522, #532. Bump com.google.guava:guava-testlib from 33.2.1-jre to 33.3.0-jre #531. From 740ed3af09e6bbb7953e1c9f9a90a8d3c749cc13 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 17:50:50 -0400 Subject: [PATCH 16/24] Javadoc - Close HTML tags - Reduce whitespace --- .../iterators/CartesianProductIterator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java index 2aea039222..a868b0942e 100644 --- a/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java +++ b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java @@ -29,7 +29,7 @@ * The iterables provided to the constructor are used in reverse order, each * until exhaustion before proceeding to the next element of the prior iterable * and repeating. Consider the following example: - * + *

*
{@code
  * List iterable1 = Arrays.asList('A', 'B', 'C');
  * List iterable2 = Arrays.asList('1', '2', '3');
@@ -41,9 +41,9 @@
  *     System.out.println(tuple.get(0) + ", " + tuple.get(1));
  * }
  * }
- * + *

* The output will be: - * + *

*
  * A, 1
  * A, 2
@@ -58,10 +58,12 @@
  * 

* The {@code remove()} operation is not supported, and will throw an * {@code UnsupportedOperationException}. + *

*

* If any of the input iterables is empty, the Cartesian product will be empty. * If any of the input iterables is infinite, the Cartesian product will be * infinite. + *

* * @param the type of the objects being permuted * @since 4.5.0 @@ -127,7 +129,6 @@ public List next() { if (!hasNext()) { throw new NoSuchElementException(); } - if (previousTuple == null) { previousTuple = new ArrayList<>(iterables.size()); for (final Iterator iterator : iterators) { @@ -135,7 +136,6 @@ public List next() { } return new ArrayList<>(previousTuple); } - for (int i = iterators.size() - 1; i >= 0; i--) { Iterator iterator = iterators.get(i); if (iterator.hasNext()) { From 3c991c01da146b98b8c1c30ff78f8762f1e888aa Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 17:59:01 -0400 Subject: [PATCH 17/24] Inline redundant package-private method that wraps Objects.requireNonNull() --- .../commons/collections4/FluentIterable.java | 2 +- .../commons/collections4/IterableUtils.java | 34 +++++++------------ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/FluentIterable.java b/src/main/java/org/apache/commons/collections4/FluentIterable.java index d3b07b88ac..c985d7e575 100644 --- a/src/main/java/org/apache/commons/collections4/FluentIterable.java +++ b/src/main/java/org/apache/commons/collections4/FluentIterable.java @@ -91,7 +91,7 @@ public static FluentIterable empty() { * @throws NullPointerException if iterable is null */ public static FluentIterable of(final Iterable iterable) { - IterableUtils.checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (iterable instanceof FluentIterable) { return (FluentIterable) iterable; } diff --git a/src/main/java/org/apache/commons/collections4/IterableUtils.java b/src/main/java/org/apache/commons/collections4/IterableUtils.java index 4b3adadca4..7066028fff 100644 --- a/src/main/java/org/apache/commons/collections4/IterableUtils.java +++ b/src/main/java/org/apache/commons/collections4/IterableUtils.java @@ -93,7 +93,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable boundedIterable(final Iterable iterable, final long maxSize) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (maxSize < 0) { throw new IllegalArgumentException("MaxSize parameter must not be negative."); } @@ -219,16 +219,6 @@ public static Iterable chainedIterable(final Iterable a, return chainedIterable(new Iterable[] {a, b, c, d}); } - /** - * Fail-fast check for null arguments. - * - * @param iterable the iterable to check - * @throws NullPointerException if iterable is null - */ - static void checkNotNull(final Iterable iterable) { - Objects.requireNonNull(iterable, "iterable"); - } - /** * Fail-fast check for null arguments. * @@ -238,7 +228,7 @@ static void checkNotNull(final Iterable iterable) { static void checkNotNull(final Iterable... iterables) { Objects.requireNonNull(iterables, "iterables"); for (final Iterable iterable : iterables) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); } } @@ -409,7 +399,7 @@ private static Iterator emptyIteratorIfNull(final Iterable iterable) { */ public static Iterable filteredIterable(final Iterable iterable, final Predicate predicate) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); Objects.requireNonNull(predicate, "predicate"); return new FluentIterable() { @Override @@ -572,7 +562,7 @@ public static boolean isEmpty(final Iterable iterable) { * @throws NullPointerException if iterable is null */ public static Iterable loopingIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -818,7 +808,7 @@ public static List> partition(final Iterable iterable, * @see ReverseListIterator */ public static Iterable reversedIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -864,7 +854,7 @@ public static int size(final Iterable iterable) { * @throws NullPointerException if iterable is null */ public static Iterable skippingIterable(final Iterable iterable, final long elementsToSkip) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (elementsToSkip < 0) { throw new IllegalArgumentException("ElementsToSkip parameter must not be negative."); } @@ -970,7 +960,7 @@ public static String toString(final Iterable iterable, */ public static Iterable transformedIterable(final Iterable iterable, final Transformer transformer) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); Objects.requireNonNull(transformer, "transformer"); return new FluentIterable() { @Override @@ -994,7 +984,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable uniqueIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -1015,7 +1005,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable unmodifiableIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (iterable instanceof UnmodifiableIterable) { return iterable; } @@ -1042,8 +1032,8 @@ public static Iterable unmodifiableIterable(final Iterable iterable) { */ public static Iterable zippingIterable(final Iterable a, final Iterable b) { - checkNotNull(a); - checkNotNull(b); + Objects.requireNonNull(a, "iterable"); + Objects.requireNonNull(b, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -1069,7 +1059,7 @@ public Iterator iterator() { * @throws NullPointerException if either of the provided iterables is null */ public static Iterable zippingIterable(final Iterable first, final Iterable... others) { - checkNotNull(first); + Objects.requireNonNull(first, "iterable"); checkNotNull(others); return new FluentIterable() { @Override From 6e273e7c04c6c730964808a80269c80497d2b3a4 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 1 Sep 2024 19:08:34 -0400 Subject: [PATCH 18/24] Use Assertions.assertInstanceOf() --- .../commons/collections4/BagUtilsTest.java | 18 +++++++++--------- .../collections4/CollectionUtilsTest.java | 9 +++++---- .../commons/collections4/ListUtilsTest.java | 3 ++- .../commons/collections4/MapUtilsTest.java | 9 +++++---- .../commons/collections4/QueueUtilsTest.java | 11 ++++++----- .../commons/collections4/SetUtilsTest.java | 3 ++- .../collections4/SplitMapUtilsTest.java | 3 ++- .../commons/collections4/TrieUtilsTest.java | 4 ++-- .../comparators/AbstractComparatorTest.java | 4 ++-- .../keyvalue/UnmodifiableMapEntryTest.java | 4 ++-- .../collections4/map/LazySortedMapTest.java | 4 ++-- .../collections4/map/SingletonMapTest.java | 5 +++-- 12 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/test/java/org/apache/commons/collections4/BagUtilsTest.java b/src/test/java/org/apache/commons/collections4/BagUtilsTest.java index 1218470c4b..7de5425c2d 100644 --- a/src/test/java/org/apache/commons/collections4/BagUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/BagUtilsTest.java @@ -17,9 +17,9 @@ package org.apache.commons.collections4; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.bag.PredicatedBag; @@ -45,7 +45,7 @@ public class BagUtilsTest { @Test public void testPredicatedBag() { final Bag bag = BagUtils.predicatedBag(new HashBag<>(), truePredicate); - assertTrue(bag instanceof PredicatedBag, "Returned object should be a PredicatedBag."); + assertInstanceOf(PredicatedBag.class, bag, "Returned object should be a PredicatedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.predicatedBag(null, truePredicate), "Expecting NullPointerException for null bag."), @@ -57,7 +57,7 @@ public void testPredicatedBag() { @Test public void testPredicatedSortedBag() { final Bag bag = BagUtils.predicatedSortedBag(new TreeBag<>(), truePredicate); - assertTrue(bag instanceof PredicatedSortedBag, "Returned object should be a PredicatedSortedBag."); + assertInstanceOf(PredicatedSortedBag.class, bag, "Returned object should be a PredicatedSortedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.predicatedSortedBag(null, truePredicate), "Expecting NullPointerException for null bag."), @@ -69,7 +69,7 @@ public void testPredicatedSortedBag() { @Test public void testSynchronizedBag() { final Bag bag = BagUtils.synchronizedBag(new HashBag<>()); - assertTrue(bag instanceof SynchronizedBag, "Returned object should be a SynchronizedBag."); + assertInstanceOf(SynchronizedBag.class, bag, "Returned object should be a SynchronizedBag."); assertThrows(NullPointerException.class, () -> BagUtils.synchronizedBag(null), "Expecting NullPointerException for null bag."); } @@ -77,7 +77,7 @@ public void testSynchronizedBag() { @Test public void testSynchronizedSortedBag() { final Bag bag = BagUtils.synchronizedSortedBag(new TreeBag<>()); - assertTrue(bag instanceof SynchronizedSortedBag, "Returned object should be a SynchronizedSortedBag."); + assertInstanceOf(SynchronizedSortedBag.class, bag, "Returned object should be a SynchronizedSortedBag."); assertThrows(NullPointerException.class, () -> BagUtils.synchronizedSortedBag(null), "Expecting NullPointerException for null bag."); } @@ -85,7 +85,7 @@ public void testSynchronizedSortedBag() { @Test public void testTransformedBag() { final Bag bag = BagUtils.transformingBag(new HashBag<>(), nopTransformer); - assertTrue(bag instanceof TransformedBag, "Returned object should be an TransformedBag."); + assertInstanceOf(TransformedBag.class, bag, "Returned object should be an TransformedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.transformingBag(null, nopTransformer), "Expecting NullPointerException for null bag."), @@ -97,7 +97,7 @@ public void testTransformedBag() { @Test public void testTransformedSortedBag() { final Bag bag = BagUtils.transformingSortedBag(new TreeBag<>(), nopTransformer); - assertTrue(bag instanceof TransformedSortedBag, "Returned object should be an TransformedSortedBag"); + assertInstanceOf(TransformedSortedBag.class, bag, "Returned object should be an TransformedSortedBag"); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.transformingSortedBag(null, nopTransformer), "Expecting NullPointerException for null bag."), @@ -109,7 +109,7 @@ public void testTransformedSortedBag() { @Test public void testUnmodifiableBag() { final Bag bag = BagUtils.unmodifiableBag(new HashBag<>()); - assertTrue(bag instanceof UnmodifiableBag, "Returned object should be an UnmodifiableBag."); + assertInstanceOf(UnmodifiableBag.class, bag, "Returned object should be an UnmodifiableBag."); assertThrows(NullPointerException.class, () -> BagUtils.unmodifiableBag(null), "Expecting NullPointerException for null bag."); assertSame(bag, BagUtils.unmodifiableBag(bag), "UnmodifiableBag shall not be decorated"); @@ -118,7 +118,7 @@ public void testUnmodifiableBag() { @Test public void testUnmodifiableSortedBag() { final SortedBag bag = BagUtils.unmodifiableSortedBag(new TreeBag<>()); - assertTrue(bag instanceof UnmodifiableSortedBag, "Returned object should be an UnmodifiableSortedBag."); + assertInstanceOf(UnmodifiableSortedBag.class, bag, "Returned object should be an UnmodifiableSortedBag."); assertThrows(NullPointerException.class, () -> BagUtils.unmodifiableSortedBag(null), "Expecting NullPointerException for null bag."); assertSame(bag, BagUtils.unmodifiableSortedBag(bag), "UnmodifiableSortedBag shall not be decorated"); diff --git a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java index 8113960678..cb507a0ecb 100644 --- a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java @@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -1746,7 +1747,7 @@ public void testPermutationsWithNullCollection() { public void testPredicatedCollection() { final Predicate predicate = PredicateUtils.instanceofPredicate(Integer.class); final Collection collection = CollectionUtils.predicatedCollection(new ArrayList<>(), predicate); - assertTrue(collection instanceof PredicatedCollection, "returned object should be a PredicatedCollection"); + assertInstanceOf(PredicatedCollection.class, collection, "returned object should be a PredicatedCollection"); } @Test @@ -2321,7 +2322,7 @@ public void testSubtractWithPredicate() { @Deprecated public void testSynchronizedCollection() { final Collection col = CollectionUtils.synchronizedCollection(new ArrayList<>()); - assertTrue(col instanceof SynchronizedCollection, "Returned object should be a SynchronizedCollection."); + assertInstanceOf(SynchronizedCollection.class, col, "Returned object should be a SynchronizedCollection."); assertThrows(NullPointerException.class, () -> CollectionUtils.synchronizedCollection(null), "Expecting NullPointerException for null collection."); @@ -2366,7 +2367,7 @@ public void testTransform2() { public void testTransformedCollection() { final Transformer transformer = TransformerUtils.nopTransformer(); final Collection collection = CollectionUtils.transformingCollection(new ArrayList<>(), transformer); - assertTrue(collection instanceof TransformedCollection, "returned object should be a TransformedCollection"); + assertInstanceOf(TransformedCollection.class, collection, "returned object should be a TransformedCollection"); } @Test @@ -2430,7 +2431,7 @@ public void testUnionNullColl2() { @Deprecated public void testUnmodifiableCollection() { final Collection col = CollectionUtils.unmodifiableCollection(new ArrayList<>()); - assertTrue(col instanceof UnmodifiableCollection, "Returned object should be a UnmodifiableCollection."); + assertInstanceOf(UnmodifiableCollection.class, col, "Returned object should be a UnmodifiableCollection."); assertThrows(NullPointerException.class, () -> CollectionUtils.unmodifiableCollection(null), "Expecting NullPointerException for null collection."); diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 3e9922abbe..3403f06dc9 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -408,7 +409,7 @@ public void testPartition() { public void testPredicatedList() { final Predicate predicate = String.class::isInstance; final List list = ListUtils.predicatedList(new ArrayList<>(), predicate); - assertTrue(list instanceof PredicatedList, "returned object should be a PredicatedList"); + assertInstanceOf(PredicatedList.class, list, "returned object should be a PredicatedList"); assertAll( () -> assertThrows(NullPointerException.class, () -> ListUtils.predicatedList(new ArrayList<>(), null), "Expecting IllegalArgumentException for null predicate."), diff --git a/src/test/java/org/apache/commons/collections4/MapUtilsTest.java b/src/test/java/org/apache/commons/collections4/MapUtilsTest.java index 676dd231f7..d292d70409 100644 --- a/src/test/java/org/apache/commons/collections4/MapUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/MapUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -737,7 +738,7 @@ public void testLazyMap() { public void testLazyMapFactory() { final Factory factory = FactoryUtils.constantFactory(Integer.valueOf(5)); Map map = MapUtils.lazyMap(new HashMap<>(), factory); - assertTrue(map instanceof LazyMap); + assertInstanceOf(LazyMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Factory) null), "Expecting NullPointerException for null factory"), @@ -747,7 +748,7 @@ public void testLazyMapFactory() { final Transformer transformer = TransformerUtils.asTransformer(factory); map = MapUtils.lazyMap(new HashMap<>(), transformer); - assertTrue(map instanceof LazyMap); + assertInstanceOf(LazyMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Transformer) null), "Expecting NullPointerException for null transformer"), @@ -811,7 +812,7 @@ public void testOrderedMap() { inMap.put("key1", "value1"); inMap.put("key2", "value2"); final Map map = MapUtils.orderedMap(inMap); - assertTrue(map instanceof OrderedMap); + assertInstanceOf(OrderedMap.class, map); } @Test @@ -876,7 +877,7 @@ public void testPopulateMultiMap() { public void testPredicatedMap() { final Predicate p = getPredicate(); final Map map = MapUtils.predicatedMap(new HashMap<>(), p, p); - assertTrue(map instanceof PredicatedMap); + assertInstanceOf(PredicatedMap.class, map); assertThrows(NullPointerException.class, () -> MapUtils.predicatedMap(null, p, p), "Expecting NullPointerException for null map."); diff --git a/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java b/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java index ca8521ceaa..268e3dfb81 100644 --- a/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.collections4; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -41,7 +42,7 @@ public class QueueUtilsTest { @Test public void testEmptyQueue() { final Queue queue = QueueUtils.emptyQueue(); - assertTrue(queue instanceof UnmodifiableQueue, "Returned object should be an UnmodifiableQueue."); + assertInstanceOf(UnmodifiableQueue.class, queue, "Returned object should be an UnmodifiableQueue."); assertTrue(queue.isEmpty(), "Returned queue is not empty."); assertThrows(UnsupportedOperationException.class, () -> queue.add(new Object()), @@ -51,7 +52,7 @@ public void testEmptyQueue() { @Test public void testPredicatedQueue() { final Queue queue = QueueUtils.predicatedQueue(new LinkedList<>(), truePredicate); - assertTrue(queue instanceof PredicatedQueue, "Returned object should be a PredicatedQueue."); + assertInstanceOf(PredicatedQueue.class, queue, "Returned object should be a PredicatedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.predicatedQueue(null, truePredicate), "Expecting NullPointerException for null queue."); @@ -63,7 +64,7 @@ public void testPredicatedQueue() { @Test public void testSynchronizedQueue() { final Queue queue = QueueUtils.synchronizedQueue(new LinkedList<>()); - assertTrue(queue instanceof SynchronizedQueue, "Returned object should be a SynchronizedQueue."); + assertInstanceOf(SynchronizedQueue.class, queue, "Returned object should be a SynchronizedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.synchronizedQueue(null), "Expecting NullPointerException for null queue."); @@ -72,7 +73,7 @@ public void testSynchronizedQueue() { @Test public void testTransformedQueue() { final Queue queue = QueueUtils.transformingQueue(new LinkedList<>(), nopTransformer); - assertTrue(queue instanceof TransformedQueue, "Returned object should be an TransformedQueue."); + assertInstanceOf(TransformedQueue.class, queue, "Returned object should be an TransformedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.transformingQueue(null, nopTransformer), "Expecting NullPointerException for null queue."); @@ -84,7 +85,7 @@ public void testTransformedQueue() { @Test public void testUnmodifiableQueue() { final Queue queue = QueueUtils.unmodifiableQueue(new LinkedList<>()); - assertTrue(queue instanceof UnmodifiableQueue, "Returned object should be an UnmodifiableQueue."); + assertInstanceOf(UnmodifiableQueue.class, queue, "Returned object should be an UnmodifiableQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.unmodifiableQueue(null), "Expecting NullPointerException for null queue."); diff --git a/src/test/java/org/apache/commons/collections4/SetUtilsTest.java b/src/test/java/org/apache/commons/collections4/SetUtilsTest.java index b3cc533379..7a1b8dd604 100644 --- a/src/test/java/org/apache/commons/collections4/SetUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/SetUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -210,7 +211,7 @@ public void testNewIdentityHashSet() { public void testpredicatedSet() { final Predicate predicate = String.class::isInstance; final Set set = SetUtils.predicatedSet(new HashSet<>(), predicate); - assertTrue(set instanceof PredicatedSet, "returned object should be a PredicatedSet"); + assertInstanceOf(PredicatedSet.class, set, "returned object should be a PredicatedSet"); assertAll( () -> assertThrows(NullPointerException.class, () -> SetUtils.predicatedSet(new HashSet<>(), null), "Expecting NullPointerException for null predicate."), diff --git a/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java b/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java index fcf312714a..50425406e0 100644 --- a/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -93,7 +94,7 @@ public void testReadableMap() { } // unmodifiable - assertTrue(map instanceof Unmodifiable); + assertInstanceOf(Unmodifiable.class, map); // check individual operations int sz = map.size(); diff --git a/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java b/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java index ec6ab5729a..3b5bc04422 100644 --- a/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java @@ -16,9 +16,9 @@ */ package org.apache.commons.collections4; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.commons.collections4.trie.PatriciaTrie; import org.apache.commons.collections4.trie.UnmodifiableTrie; @@ -32,7 +32,7 @@ public class TrieUtilsTest { @Test public void testUnmodifiableTrie() { final Trie trie = TrieUtils.unmodifiableTrie(new PatriciaTrie<>()); - assertTrue(trie instanceof UnmodifiableTrie, "Returned object should be an UnmodifiableTrie."); + assertInstanceOf(UnmodifiableTrie.class, trie, "Returned object should be an UnmodifiableTrie."); assertThrows(NullPointerException.class, () -> TrieUtils.unmodifiableTrie(null)); diff --git a/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java b/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java index f26196a8ea..4759e5d20b 100644 --- a/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java +++ b/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java @@ -17,7 +17,7 @@ package org.apache.commons.collections4.comparators; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.fail; import java.io.FileNotFoundException; @@ -159,7 +159,7 @@ public void testComparatorCompatibility() throws IOException, ClassNotFoundExcep @Test public void testComparatorIsSerializable() { final Comparator comparator = makeObject(); - assertTrue(comparator instanceof Serializable, + assertInstanceOf(Serializable.class, comparator, "This comparator should be Serializable."); } diff --git a/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java b/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java index 095473528a..a6be43ba1d 100644 --- a/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java +++ b/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java @@ -16,9 +16,9 @@ */ package org.apache.commons.collections4.keyvalue; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Map; @@ -89,7 +89,7 @@ public void testConstructors() { assertSame(key, entry2.getKey()); assertSame(value, entry2.getValue()); - assertTrue(entry instanceof Unmodifiable); + assertInstanceOf(Unmodifiable.class, entry); } @Test diff --git a/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java b/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java index 007ae2e562..418e1fccd9 100644 --- a/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java +++ b/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java @@ -19,10 +19,10 @@ import static org.apache.commons.collections4.map.LazySortedMap.lazySortedMap; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Comparator; import java.util.Map; @@ -133,7 +133,7 @@ public void testSortOrder() { public void testTransformerDecorate() { final Transformer transformer = TransformerUtils.asTransformer(oneFactory); final SortedMap map = lazySortedMap(new TreeMap<>(), transformer); - assertTrue(map instanceof LazySortedMap); + assertInstanceOf(LazySortedMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> lazySortedMap(new TreeMap<>(), (Transformer) null), "Expecting NullPointerException for null transformer"), diff --git a/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java b/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java index 7141f23ab3..dfd074ab92 100644 --- a/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java +++ b/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java @@ -17,6 +17,7 @@ package org.apache.commons.collections4.map; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.HashMap; @@ -101,7 +102,7 @@ public void testBoundedMap() { assertEquals(1, map.size()); assertTrue(map.isFull()); assertEquals(1, map.maxSize()); - assertTrue(map instanceof BoundedMap); + assertInstanceOf(BoundedMap.class, map); } @Test @@ -167,7 +168,7 @@ public void testKeyValue() { assertEquals(1, map.size()); assertEquals(ONE, map.getKey()); assertEquals(TWO, map.getValue()); - assertTrue(map instanceof KeyValue); + assertInstanceOf(KeyValue.class, map); } // public void testCreate() throws Exception { From 10366102adf03d5cd4262a57e542a999984c7ad9 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:43:32 +0530 Subject: [PATCH 19/24] Add findDuplicates --- .../apache/commons/collections4/ListUtils.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index b3dd237060..ff19fc8876 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -24,7 +24,6 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.Set; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.functors.DefaultEquator; @@ -189,19 +188,7 @@ public static List fixedSizeList(final List list) { * @since 4.5.0-M3 */ public static List findDuplicates(final List list) { - Objects.requireNonNull(list, "The input list must not be null."); - - Set seen = new HashSet<>(); - Set duplicates = new HashSet<>(); - List result = new ArrayList<>(); - - for (E element : list) { - if (!seen.add(element) && duplicates.add(element)) { - result.add(element); - } - } - - return result; + return CollectionUtils.duplicateList(list); } /** From 0e70f14cb11de6c643c33a6b3dc554bca803edb1 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:35:23 +0530 Subject: [PATCH 20/24] Add findDuplicates --- src/main/java/org/apache/commons/collections4/ListUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index ff19fc8876..89c6ad249f 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -188,7 +188,7 @@ public static List fixedSizeList(final List list) { * @since 4.5.0-M3 */ public static List findDuplicates(final List list) { - return CollectionUtils.duplicateList(list); + return IterableUtils.duplicateList(list); } /** From 277063fceb14bdff34c5ee4a574b6a4fbd7813e6 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Thu, 5 Sep 2024 00:02:01 +0530 Subject: [PATCH 21/24] Add diverse test cases for IterableUtils.duplicateList: - Mixed element types - Nested collections - Custom objects - Large-scale data - Immutable collections --- .../commons/collections4/ListUtils.java | 33 ------- .../collections4/IterableUtilsTest.java | 87 +++++++++++++++++++ .../commons/collections4/ListUtilsTest.java | 43 --------- 3 files changed, 87 insertions(+), 76 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index fd50c05267..04744234ac 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -24,7 +24,6 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.Set; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.functors.DefaultEquator; @@ -174,38 +173,6 @@ public static List fixedSizeList(final List list) { return FixedSizeList.fixedSizeList(list); } - /** - * Finds and returns a list of duplicate elements in the given list. - *

- * This method uses two sets: one for tracking seen elements and one for - * collecting duplicates. It iterates through the list once and collects - * duplicates in a result list. - *

- * - * @param the type of elements in the list - * @param list the list to check for duplicates, must not be null - * @return a list of duplicate elements, or an empty list if no duplicates are found - * @throws NullPointerException if the list is null - * @since 4.5.0-M3 - */ - public static List findDuplicates(final List list) { - Objects.requireNonNull(list, "The input list must not be null."); - - Set seen = new HashSet<>(); - Set duplicates = new HashSet<>(); - List result = new ArrayList<>(); - - for (E element : list) { - if (!seen.add(element)) { - if (duplicates.add(element)) { - result.add(element); - } - } - } - - return result; - } - /** * Gets the first element of a list. *

diff --git a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java index b2b394bbeb..6af4da29e7 100644 --- a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java @@ -37,6 +37,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.Set; import org.apache.commons.collections4.bag.HashBag; @@ -300,6 +301,92 @@ public void testDuplicatSetAllSameInDeque() { assertEquals(new HashSet<>(Arrays.asList(5)), IterableUtils.duplicateSet(input)); } + @Test + public void testDuplicateListMixedElementTypes() { + final List input = Arrays.asList(1, "a", 2, "a", 3, "b", "b"); + final List expected = Arrays.asList("a", "b"); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListNestedCollections() { + final List> input = Arrays.asList( + Arrays.asList(1, 2, 3), + Arrays.asList(1, 2, 3), + Arrays.asList(4, 5, 6), + Arrays.asList(4, 5, 6) + ); + final List> expected = Arrays.asList( + Arrays.asList(1, 2, 3), + Arrays.asList(4, 5, 6) + ); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListCustomObjects() { + class Person { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && name.equals(person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + final List input = Arrays.asList( + new Person("Linus", 30), + new Person("Torvalds", 25), + new Person("Linus", 30), + new Person("Tim", 35), + new Person("Torvalds", 25) + ); + final List expected = Arrays.asList( + new Person("Linus", 30), + new Person("Torvalds", 25) + ); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListLargeScaleData() { + final List input = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + input.add(i % 100); + } + final List expected = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + expected.add(i); + } + final List actual = IterableUtils.duplicateList(input); + assertEquals(expected, actual); + } + + @Test + public void testDuplicateListImmutableCollections() { + final List input = Collections.unmodifiableList(Arrays.asList(1, 2, 3, 1, 2, 4)); + final List expected = Arrays.asList(1, 2); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + @Test public void testFind() { Predicate testPredicate = equalPredicate(4); diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 3403f06dc9..70c0b3426b 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -103,49 +103,6 @@ public void testEquals() { assertFalse(ListUtils.isEqualList(list1, list2)); } - @Test - public void testFindDuplicatesWithDuplicates() { - List input = Arrays.asList(1, 2, 3, 2, 4, 5, 3); - List expected = Arrays.asList(2, 3); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should contain only the duplicate elements."); - } - - @Test - public void testFindDuplicatesNoDuplicates() { - List input = Arrays.asList(1, 2, 3, 4, 5); - assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as the input list has no duplicates."); - } - - @Test - public void testFindDuplicatesEmptyList() { - List input = Arrays.asList(); - assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as the input list is empty."); - } - - @Test - public void testFindDuplicatesSingleElement() { - List input = Arrays.asList(1); - assertTrue(ListUtils.findDuplicates(input).isEmpty(), "The list should be empty as there is only one element."); - } - - - @Test - public void testFindDuplicatesMultipleDuplicates() { - List input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4); - List expected = Arrays.asList(1, 2, 3, 4); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should contain all duplicate elements."); - } - - @Test - public void testFindDuplicatesAllSameElements() { - List input = Arrays.asList(5, 5, 5, 5); - List expected = Arrays.asList(5); - List actual = ListUtils.findDuplicates(input); - assertEquals(expected, actual, "The list should contain the single element as all elements are the same."); - } - @Test public void testGetFirst() { assertEquals(a, ListUtils.getFirst(fullList)); From 6423bf3756d4072fd267c308fdabc7d9b5151d50 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:31:05 +0530 Subject: [PATCH 22/24] Corrected spaces and lines --- src/main/java/org/apache/commons/collections4/ListUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/apache/commons/collections4/ListUtils.java b/src/main/java/org/apache/commons/collections4/ListUtils.java index 92a891e4ec..04744234ac 100644 --- a/src/main/java/org/apache/commons/collections4/ListUtils.java +++ b/src/main/java/org/apache/commons/collections4/ListUtils.java @@ -172,6 +172,7 @@ public static List emptyIfNull(final List list) { public static List fixedSizeList(final List list) { return FixedSizeList.fixedSizeList(list); } + /** * Gets the first element of a list. *

From bcb765bffae83678968f2ccfb8c643174984e45b Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Mon, 9 Sep 2024 00:57:04 +0530 Subject: [PATCH 23/24] Add more Comprehensive tests IterableUtils.duplicateList - Mixed element types - Nested collections - Custom objects - Large-scale data - Immutable collections --- .../collections4/IterableUtilsTest.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java index b2b394bbeb..73cfd8e1e5 100644 --- a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java @@ -38,6 +38,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.Objects; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.lang3.StringUtils; @@ -300,6 +301,92 @@ public void testDuplicatSetAllSameInDeque() { assertEquals(new HashSet<>(Arrays.asList(5)), IterableUtils.duplicateSet(input)); } + @Test + public void testDuplicateListMixedElementTypes() { + final List input = Arrays.asList(1, "a", 2, "a", 3, "b", "b"); + final List expected = Arrays.asList("a", "b"); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListNestedCollections() { + final List> input = Arrays.asList( + Arrays.asList(1, 2, 3), + Arrays.asList(1, 2, 3), + Arrays.asList(4, 5, 6), + Arrays.asList(4, 5, 6) + ); + final List> expected = Arrays.asList( + Arrays.asList(1, 2, 3), + Arrays.asList(4, 5, 6) + ); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListCustomObjects() { + class Person { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && name.equals(person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + final List input = Arrays.asList( + new Person("Linus", 30), + new Person("Torvalds", 25), + new Person("Linus", 30), + new Person("Tim", 35), + new Person("Torvalds", 25) + ); + final List expected = Arrays.asList( + new Person("Linus", 30), + new Person("Torvalds", 25) + ); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + + @Test + public void testDuplicateListLargeScaleData() { + final List input = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + input.add(i % 100); + } + final List expected = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + expected.add(i); + } + final List actual = IterableUtils.duplicateList(input); + assertEquals(expected, actual); + } + + @Test + public void testDuplicateListImmutableCollections() { + final List input = Collections.unmodifiableList(Arrays.asList(1, 2, 3, 1, 2, 4)); + final List expected = Arrays.asList(1, 2); + assertEquals(expected, IterableUtils.duplicateList(input)); + } + @Test public void testFind() { Predicate testPredicate = equalPredicate(4); From 12dccf93b9f67f66a747ace263920da76cfbaa15 Mon Sep 17 00:00:00 2001 From: HEMANTH M <128402149+hemanth0525@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:01:10 +0530 Subject: [PATCH 24/24] remove duplicate imports --- .../java/org/apache/commons/collections4/IterableUtilsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java index bf434578f3..6af4da29e7 100644 --- a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java @@ -39,7 +39,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.Objects; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.lang3.StringUtils;