我在下面有这个代码,我通过执行以下行获得了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) {
我不明白为什么会出现这种错误,因为我没有修改列表。
答案 0 :(得分:16)
请注意,Collections.unmodifiable*
不是复制集合数据,而只是将原始集合包装在特殊的包装器中。因此,如果您修改原始集合,则可能会出现此错误。
如果要创建真正独立的不可修改的集合实例:
Collections.unmodifiableCollection(new ArrayList<>(map.values()));
答案 1 :(得分:5)
在迭代map
时,您必须在另一个帖子中更新col
。 map#values
和Collections.unmodifiableCollection
都返回现有数据结构的视图,因此您正在迭代的内容(这是由堆栈跟踪见证的)是map
的条目集。