[ https://issues.apache.org/jira/browse/COLLECTIONS-663?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16968061#comment-16968061 ]
Chen edited comment on COLLECTIONS-663 at 11/6/19 6:10 AM: ----------------------------------------------------------- Hello. [~chris333] Thank you for your 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<Map.Entry<K, Collection<V>>> { AsMapEntrySetIterator(final Iterator<Map.Entry<K, Collection<V>>> iterator) { super(iterator); } @Override public Map.Entry<K, Collection<V>> next() { final Map.Entry<K, Collection<V>> entry = super.next(); final K key = entry.getKey(); final Collection<V> 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. And this modification will also avoid your problem. Thank you for your listening! was (Author: guoping1): Hello. [~chris333] Thank you for your 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<Map.Entry<K, Collection<V>>> { AsMapEntrySetIterator(final Iterator<Map.Entry<K, Collection<V>>> iterator) { super(iterator); } @Override public Map.Entry<K, Collection<V>> next() { final Map.Entry<K, Collection<V>> entry = super.next(); final K key = entry.getKey(); final Collection<V> 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. And this modification will also avoid your problem. Thank you 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<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 (v8.3.4#803005)