Java Guava:在迭代时从Multimap中删除并放回元素

时间:2013-05-19 11:08:46

标签: java guava multimap backtracking

我想要实现的目标如下:在迭代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?
    }
  }
}

1 个答案:

答案 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}}在第二个迭代器中。