ConcurrentModificationException при использовании итератора для удаления записи - PullRequest
0 голосов
/ 06 ноября 2018

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

Если вы не можете изменить 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());
    }
0 голосов
/ 06 ноября 2018

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...