[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2020-03-21 Thread Chen Guoping (Jira)


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

Chen Guoping commented on COLLECTIONS-663:
--

Any update for this issue? I'm happy to follow up if there is any concern.

Thanks!

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>  Time Spent: 10m
>  Remaining Estimate: 0h
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-11-05 Thread Chen (Jira)


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

Chen commented on COLLECTIONS-663:
--

Hello. [~chris333]

Thank you for response.

I think the representation of Multimap is \{1: A, 1: B, 2: C}. So when A and B 
are deleted, only \{2: C} is left. And asMap() method is return a map in the 
form of \{1:[A, B], 2:[C]}. In this map, \{1:[], 2:[C]} is left when a and B 
are deleted.


 If you agree with what I say above, the cause of the problem is not 
AbstractMultiMap ValueIterator.remove();

The reasons are as follows:
{code:java}
// AbstractMultiValuedMap AsMap entrySet() AsMapEntrySet AsMapEntrySetIterator 
next()
class AsMapEntrySetIterator extends 
AbstractIteratorDecorator>> {
   
AsMapEntrySetIterator(final Iterator>> 
iterator) {
super(iterator);
}
   @Override
public Map.Entry> next() {
final Map.Entry> entry = super.next();
final K key = entry.getKey();
final Collection value = entry.getValue();
return new UnmodifiableMapEntry<>(key, value);
//return new UnmodifiableMapEntry<>(key, 
wrappedCollection(key));
}
}
{code}
I think wrappedCollection(key) should not be used。if it use 
wrappedCollection(key), it willl be shown as \{1: A, 1: B, 2: C}. the asMap() 
method does not make sense.

Thank for your listening!

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-11-05 Thread Christophe Schmaltz (Jira)


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

Christophe Schmaltz commented on COLLECTIONS-663:
-

Hi [~Guoping1] ,

thank you for looking into this. I worked around my problem since then.


Maybe you want to add in the documentation of {{MultiValuedMap.mapIterator()}} 
(or better in it's implementation {{AbstractMultiValuedMap.mapIterator()}}) 
that it doesn't support {{setValue(Object)}}, as it's documented for asMap().

 

 

 

But I think the initial issue needs documentation even more:
{code:java}
@Test
public void test() {
MultiValuedMap multiMap = new 
HashSetValuedHashMap<>();
multiMap.put(1, 10);
multiMap.put(2, 20);
for (Collection innerCollection : 
multiMap.asMap().values()) {
for (Iterator 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, which is a lot 
harder to understand than the UnsupportedOperationException of the other test.

 

The {{ConcurrentModificationException}}  needs debugging to understand that it 
isn't the user who removed concurrently, but the apache-commons library itself.

 

That {{AbstractMultiValuedMap.ValuesIterator.remove()}} is calling  
{{AbstractMultiValuedMap.this.remove(key);}} is incorrect if the user was using 
an iterator over the multimap:

 

 
{code:java}
 //  AbstractMultiValuedMap.ValuesIterator.remove(): 
   @Override
public void remove() {
iterator.remove();
if (values.isEmpty()) { 
// this is buggy if the user was iterating over the 
AbstractMultiValuedMap
AbstractMultiValuedMap.this.remove(key);
}
}
{code}
Maybe MultiValuedMap.asMap() needs some documentation that it doesn't support 
{{remove()}} in case of nested usage of {{iterator()}}.

Or find a way to call enclosingIterator.remove():
{code:java}
 //  AbstractMultiValuedMap.ValuesIterator.remove(): 
   @Override
public void remove() {
iterator.remove();
if (values.isEmpty()) {
if (hasEnclosingIterator()) {
enclosingIterator.remove(); // nested iteration
} else {
AbstractMultiValuedMap.this.remove(key); // non nested usage
}
}
}
{code}
 hasEnclosingIterator() and enclosingIterator have to be implemented, somehow :D

 

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-11-04 Thread Chen (Jira)


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

Chen commented on COLLECTIONS-663:
--

Hi,[~chris333]

MapIterator.setValue() really is not supported, there is a not elegant code to 
implement your problem what I understand.
{code:java}
//代码占位符
public void testWhatINeedToWork() {
ListValuedMap multiMap = new 
ArrayListValuedHashMap<>();
multiMap.put(1, 10);
multiMap.put(1, 20);
multiMap.put(2, 10);
System.out.println(multiMap);
for(Collection col: multiMap.asMap().values()){
if(col instanceof  List){
List list = (List) col;
for(ListIterator it = list.listIterator(); it.hasNext(); ){
Integer value = (Integer) it.next();
if(value % 2== 0){
it.set(value*2);
}
}
}
}
System.out.println(multiMap);
}
{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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-11-02 Thread Chen (Jira)


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

Chen commented on COLLECTIONS-663:
--

Hi,Gary D.Gregory

See code, In the AbstractMultiValuedMap.java,

1、AbstractMultiValuedMap.MapIterator() methos will return private 
MultiValuedMapIterator class

2、MultiValuedMapIterator class will call 
AbstractMultiValuedMap.entries().iterator()

3、AbstractMultiValuedMap.entries() will return private EntryValues class

4、EntryValues class will return LazyIteratorChain overide nextIterator which 
call MultiValuedMapEntry class

5、MultiValuedMapEntry class setValue() method throw 
UnsupportedOperationException. 

so MapIterator.setValue() is not support!

Ithink it is a proplem, Should we solve this problem by submitting a PR?

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-11-02 Thread Chen (Jira)


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

Chen commented on COLLECTIONS-663:
--

Hello, Gary D.Gregory

In this [PR|[https://github.com/apache/commons-collections/pull/108/files]], 
the testMultiValuedMapIterator() method test MapIterator.setValue() .That 
MapIterator.setValue() is really not supported。In ArrayListValuedHashMap, 
HashSetValuedHashMap, TransformedMultiValuedMap and UnmodifiableMultiValuedMap 
will throw UnsupportedOperationException when use MapIterator.setValue().

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v8.3.4#803005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2019-07-05 Thread Gary Gregory (JIRA)


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

Gary Gregory commented on COLLECTIONS-663:
--

Waiting for PR for a new test?

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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
(v7.6.3#76005)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2017-11-05 Thread Bruno P. Kinoshita (JIRA)

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

Bruno P. Kinoshita commented on COLLECTIONS-663:


Oh, not sure if there's a better way. Got what I think is your desired result 
with a not very elegant code.

{code:java}
public void testWhatINeedToWork() {
// ArrayListValuedHashMap multiMap = new 
ArrayListValuedHashMap<>();
MultiValuedMap multiMap = new 
HashSetValuedHashMap<>();

multiMap.put(1, 10);
multiMap.put(1, 11);
multiMap.put(2, 20);

MapIterator it = multiMap.mapIterator();
while (it.hasNext()) {
Integer key = it.next();
if (key % 2 == 0) {
Collection values = multiMap.get(key);
multiMap.putAll(key * 2, values);
it.remove();
}
}
}
{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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2017-11-05 Thread Christophe Schmaltz (JIRA)

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

Christophe Schmaltz commented on COLLECTIONS-663:
-

Than you for your response.

I once used the {{MapIterator}}, sadly I found out that it doesn't support what 
I try to achieve:
{code}  @Test
public void testWhatINeedToWork() {
// ArrayListValuedHashMap multiMap = new 
ArrayListValuedHashMap<>();
MultiValuedMap multiMap = new 
HashSetValuedHashMap<>();

multiMap.put(1, 10);
multiMap.put(1, 11);
multiMap.put(2, 20);
Iterator it = multiMap.mapIterator();
for (MapIterator iterator = 
multiMap.mapIterator(); iterator.hasNext();) {
iterator.next();
Integer value = iterator.getValue();
if ((value % 2) == 0) {
// Integer is immutable, we need to replace 
using setValue(.)
iterator.setValue(value * 2);
}
}
}{code}
My issue was that {{MapIterator.setValue(.)}} is not supported.

(My current workaround is storing the elements I need to change in a list, and 
pushing them back in the map afterwards)

I understand the difficulty in implementing it for {{HashSetValuedHashMap}} 
though, as the {{HashSet.iterator}} doesn't support it either (sadly, that's 
what I need).
I observed that {{ArrayListValuedHashMap}} doesn't support {{setValue(.)}} 
either (should be possible, as {{ArrayList.listIterator}} has this feature.

> 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
>Assignee: Bruno P. Kinoshita
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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)


[jira] [Commented] (COLLECTIONS-663) Unexpected ConcurrentModificationException when altering Collection of a MultiValuedMap

2017-11-04 Thread Bruno P. Kinoshita (JIRA)

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

Bruno P. Kinoshita commented on COLLECTIONS-663:


I believe the Javadocs from asMap from MultiValuedMap indicate it works for as 
a view for a state in the collection. If you have to alter the map or the 
values collection, I'd try first using the mapIterator() method from the 
MultiValuedMap. It returns a custom iterator.

The following altered code works for me:

{code:java}
public void testAlteringCollection() {
MultiValuedMap multiMap = new 
HashSetValuedHashMap<>();
multiMap.put(1, 10);
multiMap.put(2, 20);
Iterator it = multiMap.mapIterator();
for (Iterator iterator = multiMap.mapIterator(); 
iterator.hasNext();) {
Integer i = iterator.next();
iterator.remove(); // only the innerCollection is altered
}
}
{code}

Does it help? Bruno

> 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
>Priority: Trivial
>
> Testcase:
> {code}@Test
>   public void test() {
>   MultiValuedMap multiMap = new 
> HashSetValuedHashMap<>();
>   multiMap.put(1, 10);
>   multiMap.put(2, 20);
>   for (Collection innerCollection : 
> multiMap.asMap().values()) {
>   for (Iterator 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)