ConcurrentModificationException в неизменяемой коллекции

У меня есть этот код ниже, и я получаю исключение ConcurrentModificationException, выполнив следующую строку:

filterCardsToDevice(getCollection());

код:

private List<MyClass> filterCardsToDevice(Collection<MyClass> col) {
    final List<MyClass> newList = new ArrayList<MyClass>();

    for (MyClass myObj : col) {
        long id = myObj.getId();
        if (id < 0 || id > 0xFFFFFFFFl) {
            // just a log here
        } else {
            newList.add(myObj);
        }
    }

    return newList;
}

private final Map<Long, MyClass> map = new HashMap<Long, MyClass>();

public Collection<MyClass> getCollection() {
    synchronized (map) {
        return Collections.unmodifiableCollection(map.values());
    }
}

Стек:

at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)                 
at java.util.HashMap$ValueIterator.next(HashMap.java:871)                 
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)

Точно в строке foreach:

for (MyClass myObj : col) {

Я не понимаю, почему возникает эта ошибка, потому что я не изменяю список.


person Pedro Estevao    schedule 01.11.2013    source источник
comment
Это не дублированный файл, это запрос на неизменяемую коллекцию.   -  person Anthony C    schedule 16.08.2019


Ответы (2)


Имейте в виду, что Collections.unmodifiable* не копирует данные коллекции, а только помещает исходную коллекцию в специальную оболочку. Поэтому, если вы измените исходную коллекцию, вы можете получить эту ошибку.


Если вы хотите создать действительно независимый неизменяемый экземпляр коллекции:

Collections.unmodifiableCollection(new ArrayList<>(map.values()));
person Pavel Horal    schedule 01.11.2013

Вы должны обновлять map в другом потоке, пока выполняете итерацию через col. И map#values, и Collections.unmodifiableCollection возвращают представления существующих структур данных, поэтому то, что вы повторяете (и это засвидетельствовано вашей трассировкой стека), является набором записей вашего map.

person Marko Topolnik    schedule 01.11.2013