如何在Java中修改对象时迭代对象?

可能重复:
Java:在迭代集合时高效等效删除
在迭代它时从java中的集合中删除项目

我正在尝试遍历HashMap

 Map group0 = new HashMap(); 

…并提取group0每个元素。 这是我的方法:

 // iterate through all Members in group 0 that have not been assigned yet for (Map.Entry entry : group0.entrySet()) { // determine where to assign 'entry' iEntryGroup = hasBeenAccusedByGroup(entry.getKey()); if (iEntryGroup == 1) { assign(entry.getKey(), entry.getValue(), 2); } else { assign(entry.getKey(), entry.getValue(), 1); } } 

这里的问题是每次调用assign()都会从group0删除元素,从而修改它的大小,从而导致以下错误:

 Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) at java.util.HashMap$EntryIterator.next(HashMap.java:834) at java.util.HashMap$EntryIterator.next(HashMap.java:832) at liarliar$Bipartite.bipartition(liarliar.java:463) at liarliar$Bipartite.readFile(liarliar.java:216) at liarliar.main(liarliar.java:483) 

那么……当它动态变化时,我如何循环遍历group0的元素?

其他人提到了正确的解决方案而没有实际拼写出来。 所以这里是:

 Iterator> iterator = group0.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); // determine where to assign 'entry' iEntryGroup = hasBeenAccusedByGroup(entry.getKey()); if (iEntryGroup == 1) { assign(entry.getKey(), entry.getValue(), 2); } else { assign(entry.getKey(), entry.getValue(), 1); } // I don't know under which conditions you want to remove the entry // but here's how you do it iterator.remove(); } 

此外,如果要在assign函数中安全地更改映射,则需要传入迭代器(其中只能使用remove函数一次)或更改值的条目。

正如我在这里的回答所说:

迭代集合,在循环中删除时避免ConcurrentModificationException

使用Iterator.remove()

您可以使用ConcurrentHashMap

  • Brian Goetz在此解释了实施细节
  • 并发集合类的更多解释

在您的特定情况下,我不会修改HashMap的结构,只是将您想要删除的值清空。 然后,如果您最终访问空值,则跳过它。

在一般情况下,我更喜欢使用Stack来做这样的事情,因为它们特别容易可视化,所以我倾向于减少边界条件的问题(只是保持弹出’直到空)。

如果要在循环时修改集合,则需要使用实际迭代器及其remove方法。 使用foreach结构没有任何方法可以做到这一点。

如果您尝试在一次迭代中删除多个条目,则需要循环遍历地图未支持的内容。

 Set keys = new HashSet(group0.keySet()); for (String key : keys) { if (group0.containsKey(key)) { Integer value = group0.get(key); //your stuff } } 

在这种情况下,如何assign修改group0 ? 需要更多细节。 通常,您无法在迭代时修改集合。 您可以通过Iterator接口进行修改。