我想要实现的目标如下:在迭代Multimap<K,V>
的键和值时,我想从此列表中删除并放回元素。我尝试过的任何方法最终都会出现在ConcurrentModificationException中。实施回溯搜索需要使用此删除和回放方法(请参阅此处:Implementing a backtrack search with heuristic?)
这可能看起来像:
Multimap<K,V> multimap = HashMultimap.create();
Iterator keyIterator = multimap.keySet().iterator();
while(keyIterator.hasNext()) {
K key = keyIterator.next();
Collection values = multimap.get(key);
Iterator valueIterator = values.iterator();
while(valueIterator.hasNext()) {
V myValue = valueIterator.next();
if(special) {
valueIterator.remove();
keyIterator.remove();
// recursion
// put back Collection with key but without myValue <-- HOW?
}
}
}
答案 0 :(得分:3)
一种解决方案是迭代keySet
的副本,例如
K[] array = multiMap.keySet().toArray(new K[0]);
for(int i = 0; i < array.length; i++) {
K key = array[i];
...
}
对基础地图的更改不会反映在array
中,因此如果您在其上使用ConcurrentModificationException
,则不会获得Iterator
,并且您将无法获得任何奇怪的行为,如果你用for循环迭代它。
另一种选择是将MultiMap
的源代码复制粘贴到新的集合MyMultiMap
中,除非您使用{{1}替换顶级HashMap
- 后者的迭代器不会抛出ConcurrentHashMap
。
另一种选择是将两个循环合并为一个循环,并直接在地图的ConcurrentModificationExceptions
上迭代 - 这样你只有一个迭代器,所以你不会遇到一个迭代器导致的问题{ {1}}在第二个迭代器中。