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 e218502f9 Fix stale size in AbstractMapMultiSet view iterator remove 
(#701)
e218502f9 is described below

commit e218502f9f82237404bbce8e8ba5f81ffb467198
Author: Dexter.k <[email protected]>
AuthorDate: Fri Jul 3 18:06:13 2026 +0000

    Fix stale size in AbstractMapMultiSet view iterator remove (#701)
    
    * fix stale size in AbstractMapMultiSet view iterator remove
    
    * move view iterator remove test to AbstractMultiSetTest to cover all 
subclasses
---
 .../collections4/multiset/AbstractMapMultiSet.java |  6 ++++-
 .../multiset/AbstractMultiSetTest.java             | 28 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git 
a/src/main/java/org/apache/commons/collections4/multiset/AbstractMapMultiSet.java
 
b/src/main/java/org/apache/commons/collections4/multiset/AbstractMapMultiSet.java
index 85eb3dbc0..fc1dc9907 100644
--- 
a/src/main/java/org/apache/commons/collections4/multiset/AbstractMapMultiSet.java
+++ 
b/src/main/java/org/apache/commons/collections4/multiset/AbstractMapMultiSet.java
@@ -92,7 +92,10 @@ public abstract class AbstractMapMultiSet<E> extends 
AbstractMultiSet<E> {
             if (!canRemove) {
                 throw new IllegalStateException("Iterator remove() can only be 
called once after next()");
             }
+            final int count = last.getCount();
             decorated.remove();
+            parent.size -= count;
+            parent.modCount++;
             last = null;
             canRemove = false;
         }
@@ -267,7 +270,8 @@ public abstract class AbstractMapMultiSet<E> extends 
AbstractMultiSet<E> {
             }
             final int count = parent.getCount(lastElement);
             super.remove();
-            parent.remove(lastElement, count);
+            parent.size -= count;
+            parent.modCount++;
             lastElement = null;
             canRemove = false;
         }
diff --git 
a/src/test/java/org/apache/commons/collections4/multiset/AbstractMultiSetTest.java
 
b/src/test/java/org/apache/commons/collections4/multiset/AbstractMultiSetTest.java
index a4887c867..966ae6f1b 100644
--- 
a/src/test/java/org/apache/commons/collections4/multiset/AbstractMultiSetTest.java
+++ 
b/src/test/java/org/apache/commons/collections4/multiset/AbstractMultiSetTest.java
@@ -568,6 +568,34 @@ public abstract class AbstractMultiSetTest<T> extends 
AbstractCollectionTest<T>
         assertFalse(it2.hasNext());
     }
 
+    @Test
+    @SuppressWarnings("unchecked")
+    void testMultiSetViewIteratorRemoveKeepsSizeConsistent() {
+        if (!isRemoveSupported()) {
+            return;
+        }
+        // removing through uniqueSet()/entrySet() drops the whole entry, so
+        // size() must fall by that entry's count and the views stay consistent
+        final MultiSet<T> multiset = makeObject();
+        multiset.add((T) "A", 3);
+        multiset.add((T) "B", 2);
+
+        final Iterator<T> unique = multiset.uniqueSet().iterator();
+        final T removed = unique.next();
+        final int removedCount = multiset.getCount(removed);
+        unique.remove();
+        assertEquals(5 - removedCount, multiset.size());
+        assertFalse(multiset.contains(removed));
+        assertEquals(multiset.size(), multiset.toArray().length);
+
+        final Iterator<MultiSet.Entry<T>> entries = 
multiset.entrySet().iterator();
+        entries.next();
+        entries.remove();
+        assertEquals(0, multiset.size());
+        assertTrue(multiset.isEmpty());
+        assertEquals(0, multiset.toArray().length);
+    }
+
     @Test
     @SuppressWarnings("unchecked")
     void testMultiSetRemove() {

Reply via email to