使用迭代器删除条目时发生ConcurrentModificationException

时间:2018-11-06 12:17:43

标签: java swing hashmap concurrentmodification

我有一段简单的代码循环遍历一个映射,检查每个条目的条件,并在该条件为true时对该条目执行一个方法。之后,该条目将从地图中删除。 要从地图中删除条目,我使用Iterator来避免使用ConcurrentModificationException

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
    }
}

2 个答案:

答案 0 :(得分:2)

如果无法将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());
    }

答案 1 :(得分:1)

当您在多个线程中对对象进行操作时,请使用ConcurrentHashMap代替HashMap。 HashMap类不是线程安全的,并且也不允许此类操作。请参阅下面的链接以获取与此相关的更多信息。

https://www.google.co.in/amp/s/www.geeksforgeeks.org/difference-hashmap-concurrenthashmap/amp/

让我知道更多信息。