java - 使用迭代器删除条目时出现 ConcurrentModificationException
问题描述
我有一段简单的代码循环遍历映射,检查每个条目的条件,如果条件为真,则在条目上执行一个方法。之后,该条目将从地图中删除。要从地图中删除一个条目,我使用 anIterator
来避免ConcurrentModificationException
's。
除了我的代码确实抛出异常,在这一it.remove()
行:
Caused by: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.remove(Unknown Source) ~[?:1.8.0_161]
at package.Class.method(Class.java:34) ~[Class.class:?]
经过长时间的搜索,我找不到解决此问题的方法,所有答案都建议使用该Iterator.remove()
方法,但我已经在使用它。的文档Map.entrySet()
明确指定可以使用该Iterator.remove()
方法从集合中删除元素。
任何帮助将不胜感激。
我的代码:
Iterator<Entry<K, V>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<K, V> en = it.next();
if (en.getValue().shouldRun()) {
EventQueue.invokeLater(()->updateSomeGui(en.getKey())); //the map is in no way modified in this method
en.getValue().run();
it.remove(); //line 34
}
}
解决方案
如果您无法更改HashMap
为ConcurrentHashMap
您可以使用另一种方法来处理您的代码。
您可以创建包含要删除的条目的条目列表,然后遍历它们并将它们从原始映射中删除。
例如
HashMap<String, String> map = new HashMap<>();
map.put("1", "a1");
map.put("2", "a2");
map.put("3", "a3");
map.put("4", "a4");
map.put("5", "a5");
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
List<Map.Entry<String, String>> entries = new ArrayList<>();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
if (next.getKey().equals("2")) {
/* instead of remove
iterator.remove();
*/
entries.add(next);
}
}
for (Map.Entry<String, String> entry: entries) {
map.remove(entry.getKey());
}