不可修改集合中的ConcurrentModificationException

Ped*_*vao 9 java collections unmodifiable concurrentmodification

我在下面有这个代码,我通过执行以下行得到一个ConcurrentModificationException:

filterCardsToDevice(getCollection());
Run Code Online (Sandbox Code Playgroud)

代码:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

堆栈是:

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)
Run Code Online (Sandbox Code Playgroud)

正好在foreach线上:

for (MyClass myObj : col) {
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会出现这个错误,因为我没有修改列表.

Pav*_*ral 18

要知道,Collections.unmodifiable*不是抄袭收集数据,但只有包装原始集合在一个特殊的包装.因此,如果您修改原始集合,则可能会出现此错误.


如果要创建真正独立的不可修改的集合实例:

Collections.unmodifiableCollection(new ArrayList<>(map.values()));
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 5

map在迭代时,您必须在另一个线程中更新col.双方map#valuesCollections.unmodifiableCollection返回意见现有的数据结构,你迭代等什么了(这是由您的堆栈跟踪目击)是入门设置你的map.