This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new 5b7ca64b1 Fix collate keeping duplicate nulls when includeDuplicates 
is false (#715)
5b7ca64b1 is described below

commit 5b7ca64b122fade798413a14bfb5276a770aaec1
Author: Naveed Khan <[email protected]>
AuthorDate: Sat Jul 18 13:56:05 2026 +0000

    Fix collate keeping duplicate nulls when includeDuplicates is false (#715)
---
 src/changes/changes.xml                                       |  1 +
 .../java/org/apache/commons/collections4/CollectionUtils.java |  4 +++-
 .../org/apache/commons/collections4/CollectionUtilsTest.java  | 11 +++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5b7045aaf..ec165e974 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,7 @@
   <body>
   <release version="4.6.0" date="YYYY-MM-DD" description="This is a feature 
and maintenance release. Java 8 or later is required.">
     <!-- FIX -->
+    <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary 
Gregory">CollectionUtils.collate(Iterable, Iterable, Comparator, boolean) does 
not remove duplicate null elements when includeDuplicates is false.</action>
     <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary 
Gregory">DualHashBidiMap, DualLinkedHashBidiMap, and DualTreeBidiMap entrySet() 
Map.Entry.setValue(Object) returns the new value instead of the previous 
value.</action>
     <action type="fix" dev="ggregory" due-to="Naveed Khan, Gary 
Gregory">AbstractMapBag and AbstractMapMultiSet.add(Object, int) overflow the 
size and element count past Integer.MAX_VALUE.</action>
     <action type="fix" dev="ggregory" due-to="Naveed 
Khan">CompositeCollection, CompositeSet, CompositeMap, AbstractMultiValuedMap 
and AbstractMultiSet size() overflow int when the total exceeds 
Integer.MAX_VALUE.</action>
diff --git a/src/main/java/org/apache/commons/collections4/CollectionUtils.java 
b/src/main/java/org/apache/commons/collections4/CollectionUtils.java
index 1d7209446..966d323fd 100644
--- a/src/main/java/org/apache/commons/collections4/CollectionUtils.java
+++ b/src/main/java/org/apache/commons/collections4/CollectionUtils.java
@@ -481,12 +481,14 @@ public class CollectionUtils {
         }
         final ArrayList<O> mergedList = new ArrayList<>(totalSize);
         O lastItem = null;
+        boolean first = true;
         while (iterator.hasNext()) {
             final O item = iterator.next();
-            if (lastItem == null || !lastItem.equals(item)) {
+            if (first || !Objects.equals(lastItem, item)) {
                 mergedList.add(item);
             }
             lastItem = item;
+            first = false;
         }
         mergedList.trimToSize();
         return mergedList;
diff --git 
a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java 
b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java
index 4607cc2b6..99ddfa302 100644
--- a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java
+++ b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java
@@ -647,6 +647,17 @@ class CollectionUtilsTest extends MockTestCase {
         assertEquals(combinedList, result2, "Merge two lists 2 - ignore 
duplicates");
     }
 
+    @Test
+    void testCollateIgnoreDuplicatesWithNullElements() {
+        final Comparator<String> nullsFirst = 
Comparator.nullsFirst(Comparator.<String>naturalOrder());
+        final List<String> left = Arrays.asList(null, "a");
+        final List<String> right = Arrays.asList(null, "a");
+        // a null element is a legal, sorted value here, so consecutive nulls 
must
+        // collapse just like any other duplicate when includeDuplicates is 
false
+        assertEquals(Arrays.asList(null, "a"), CollectionUtils.collate(left, 
right, nullsFirst, false));
+        assertEquals(Arrays.asList(null, null, "a", "a"), 
CollectionUtils.collate(left, right, nullsFirst, true));
+    }
+
     @Test
     void testCollect() {
         final Transformer<Number, Long> transformer = 
TransformerUtils.constantTransformer(2L);

Reply via email to