[ 
https://issues.apache.org/jira/browse/COLLECTIONS-663?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Christophe Schmaltz updated COLLECTIONS-663:
--------------------------------------------
    Description: 
Testcase:
{code}  @Test
        public void test() {
                MultiValuedMap<Integer, Integer> multiMap = new 
HashSetValuedHashMap<>();
                multiMap.put(1, 10);
                multiMap.put(2, 20);
                for (Collection<Integer> innerCollection : 
multiMap.asMap().values()) {
                        for (Iterator<Integer> iterator = 
innerCollection.iterator(); iterator.hasNext();) {
                                Integer i = iterator.next();
                                iterator.remove(); // only the innerCollection 
is altered
                        }
                        // innerCollection.add(6); // adding stuff back should 
also work...
                }
        }{code}
This test unexpectedly throws a ConcurrentModificationException.
The issue is that when calling {{iterator.remove()}} the 
{{AbstractMultiValuedMap.ValuesIterator}} detects that the Collection is empty 
and calls {{AbstractMultiValuedMap.this.remove(key);}}.

It may be better if the iterator of the inner collection had a reference on the 
iterator if the outer map and called {{containerIterator.remove()}} instead.
*Note:* this solution would again present issues if the user tries to add new 
elements in this now empty collection (which was removed from the parent).


In the current state, it is quite unclear why an exception is thrown, without 
debugging the code. 


  was:
Testcase:
{code}  @Test
        public void test() {
                MultiValuedMap<Integer, Integer> multiMap = new 
HashSetValuedHashMap<>();
                multiMap.put(1, 10);
                multiMap.put(2, 20);
                for (Collection<Integer> innerCollection : 
multiMap.asMap().values()) {
                        for (Iterator<Integer> iterator = 
innerCollection.iterator(); iterator.hasNext();) {
                                Integer i = iterator.next();
                                iterator.remove(); // only the innerCollection 
is altered
                        }
                }
        }{code}
This test unexpectedly throws a ConcurrentModificationException.
The issue is that when calling {{iterator.remove()}} the 
{{AbstractMultiValuedMap.ValuesIterator}} detects that the Collection is empty 
and calls {{AbstractMultiValuedMap.this.remove(key);}}.

It may be better if the iterator of the inner collection had a reference on the 
iterator if the outer map and called {{containerIterator.remove()}} instead.
*Note:* this solution would again present issues if the user tries to add new 
elements in this now empty collection (which was removed from the parent).


In the current state, it is quite unclear why an exception is thrown, without 
debugging the code. 



> Unexpected ConcurrentModificationException when altering Collection of a 
> MultiValuedMap
> ---------------------------------------------------------------------------------------
>
>                 Key: COLLECTIONS-663
>                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-663
>             Project: Commons Collections
>          Issue Type: Bug
>            Reporter: Christophe Schmaltz
>
> Testcase:
> {code}        @Test
>       public void test() {
>               MultiValuedMap<Integer, Integer> multiMap = new 
> HashSetValuedHashMap<>();
>               multiMap.put(1, 10);
>               multiMap.put(2, 20);
>               for (Collection<Integer> innerCollection : 
> multiMap.asMap().values()) {
>                       for (Iterator<Integer> iterator = 
> innerCollection.iterator(); iterator.hasNext();) {
>                               Integer i = iterator.next();
>                               iterator.remove(); // only the innerCollection 
> is altered
>                       }
>                       // innerCollection.add(6); // adding stuff back should 
> also work...
>               }
>       }{code}
> This test unexpectedly throws a ConcurrentModificationException.
> The issue is that when calling {{iterator.remove()}} the 
> {{AbstractMultiValuedMap.ValuesIterator}} detects that the Collection is 
> empty and calls {{AbstractMultiValuedMap.this.remove(key);}}.
> It may be better if the iterator of the inner collection had a reference on 
> the iterator if the outer map and called {{containerIterator.remove()}} 
> instead.
> *Note:* this solution would again present issues if the user tries to add new 
> elements in this now empty collection (which was removed from the parent).
> In the current state, it is quite unclear why an exception is thrown, without 
> debugging the code. 



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to