ConcurrentModificationException при использовании итератора для удаления записи

У меня есть простая часть кода, которая проходит через карту, проверяет условие для каждой записи и выполняет метод записи, если это условие истинно. После этого запись удаляется с карты. Чтобы удалить запись с карты, я использую 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 ответа


Используйте ConcurrentHashMap вместо HashMap, поскольку вы воздействуете на объект в нескольких потоках. Класс HashMap не является потокобезопасным и также не допускает такой операции. См. Ссылку ниже для получения дополнительной информации.

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

Дайте мне знать для получения дополнительной информации.


Если вы не можете изменить 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());
    }

Есть идеи?

10000