可能重复:
Java: Efficient Equivalent to Removing while Iterating a Collection
Removing items from a collection in java while iterating over it
我正在尝试遍历HashMap
:
Map<String, Integer> group0 = new HashMap<String, Integer>();
...并提取group0
中的每个元素。这是我的方法:
// iterate through all Members in group 0 that have not been assigned yet
for (Map.Entry<String, Integer> 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
中的元素?
答案 0 :(得分:7)
其他人已经提到了正确的解决方案而没有实际拼写出来。所以这就是:
Iterator<Map.Entry<String, Integer>> iterator =
group0.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> 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函数一次)或更改值的条目。
答案 1 :(得分:3)
正如我在这里的回答所说:
Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop
使用Iterator.remove()
答案 2 :(得分:1)
您可以使用ConcurrentHashMap
答案 3 :(得分:1)
在您的特定情况下,我不会修改HashMap的结构,而只是将要删除的值为空。然后,如果您最终访问空值,则跳过它。
在一般情况下,我更喜欢使用Stack来做这样的事情,因为它们特别容易可视化,所以我倾向于减少边界条件的问题(只是保持弹出'直到空)。
答案 4 :(得分:0)
如果要在循环时修改集合,则需要使用实际迭代器及其remove方法。使用foreach结构实际上没有任何方法可以做到这一点。
如果您尝试在一次迭代中删除多个条目,则需要循环覆盖地图未支持的内容。
Set<String> keys = new HashSet<String>(group0.keySet());
for (String key : keys) {
if (group0.containsKey(key)) {
Integer value = group0.get(key);
//your stuff
}
}
答案 5 :(得分:0)
在这种情况下,assign
如何修改group0
?需要更多细节。通常,您无法在迭代时修改集合。您可以通过Iterator界面进行修改。