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 eca074f6e Fix AbstractMapBag.retainAll removing all copies when the 
other bag has more (#692)
eca074f6e is described below

commit eca074f6e218df3a1da6da24e302f6d50914870b
Author: Vasiliy Mikhailov <[email protected]>
AuthorDate: Sat Jun 27 17:25:34 2026 +0400

    Fix AbstractMapBag.retainAll removing all copies when the other bag has 
more (#692)
    
    * Fix AbstractMapBag.retainAll removing all copies when other bag has more
    
    retainAll(Bag) is meant to keep, for each element, the minimum of this
    bags cardinality and the other bags cardinality. The else branch removed
    all copies of an element whenever the guarded case (1 <= otherCount <=
    myCount) did not apply - which also covers otherCount > myCount. So when
    the other bag contained MORE copies than this bag, every copy was removed
    instead of all being kept.
    
    Only remove all copies when otherCount == 0; when otherCount > myCount no
    copies are removed, leaving the bags own cardinality intact.
    
    Signed-off-by: Vasiliy Mikhailov <[email protected]>
    
    * Remove useless blank line.
    
    ---------
    
    Signed-off-by: Vasiliy Mikhailov <[email protected]>
    Co-authored-by: Gary Gregory <[email protected]>
---
 .../commons/collections4/bag/AbstractMapBag.java      |  2 +-
 .../commons/collections4/bag/AbstractBagTest.java     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

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 bafd162e3..9ec681e09 100644
--- a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java
+++ b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java
@@ -497,7 +497,7 @@ public abstract class AbstractMapBag<E> implements Bag<E> {
             final int otherCount = other.getCount(current);
             if (1 <= otherCount && otherCount <= myCount) {
                 excess.add(current, myCount - otherCount);
-            } else {
+            } else if (otherCount == 0) {
                 excess.add(current, myCount);
             }
         }
diff --git 
a/src/test/java/org/apache/commons/collections4/bag/AbstractBagTest.java 
b/src/test/java/org/apache/commons/collections4/bag/AbstractBagTest.java
index eea933342..4ea3a6801 100644
--- a/src/test/java/org/apache/commons/collections4/bag/AbstractBagTest.java
+++ b/src/test/java/org/apache/commons/collections4/bag/AbstractBagTest.java
@@ -713,4 +713,23 @@ public abstract class AbstractBagTest<T> extends 
AbstractCollectionTest<T> {
         }
     }
 
+
+    @Test
+    @SuppressWarnings("unchecked")
+    void testBagRetainAllOtherHasMoreCopies() {
+        if (!isAddSupported()) {
+            return;
+        }
+        final Bag<T> bag = makeObject();
+        bag.add((T) "A", 2);
+        bag.add((T) "B", 3);
+        final Bag<T> other = makeObject();
+        other.add((T) "A", 5);
+        other.add((T) "B", 10);
+        bag.retainAll(other);
+        // When other has MORE copies, we should keep ALL of ours (the 
intersection keeps min)
+        assertEquals(2, bag.getCount("A"), "Should keep 2 copies of A when 
other has 5");
+        assertEquals(3, bag.getCount("B"), "Should keep 3 copies of B when 
other has 10");
+        assertEquals(5, bag.size(), "Should have 5 total items");
+    }
 }

Reply via email to