1

我想要实现的是:在迭代 a 的键和值时Multimap<K,V>,我想从这个列表中删除并放回元素。我尝试过的任何方法都以 ConcurrentModificationException 告终。这种remove-and-put-back-approach 是实现回溯搜索所必需的(参见此处: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?
    }
  }
}
4

1 回答 1

3

一种解决方案是遍历 的副本keySet,例如

K[] array = multiMap.keySet().toArray(new K[0]);
for(int i = 0; i < array.length; i++) {
    K key = array[i];
    ...
}

对底层地图的更改不会反映在 中array,因此如果在其上使用 an 则不会得到 a ConcurrentModificationException,如果使用Iteratorfor 循环对其进行迭代,也不会出现任何奇怪的行为。

另一种选择是将源代码复制粘贴MultiMap到新集合MyMultiMap中,除非您将顶级替换HashMapConcurrentHashMap- 后者的迭代器不会抛出ConcurrentModificationExceptions

另一种选择是将两个循环合并为一个循环,并直接在地图上进行迭代entries- 这样您将只有一个迭代器,因此您不会遇到一个迭代器导致ConcurrentModificationExceptions第二个迭代器的问题。

于 2013-05-19T15:18:24.003 回答