问题
I have this code below, and I'm getting a ConcurrentModificationException by executing the following line:
filterCardsToDevice(getCollection());
the code:
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());
}
}
The stack is:
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)
Exactly on foreach line:
for (MyClass myObj : col) {
I don't see why this error occurs, because I'm not modifying the list.
回答1:
Be aware, that Collections.unmodifiable*
is not copying collection data, but only wrapping the original collection in a special wrapper. So if you modify the original collection, you can get this error.
If you want to create really independent unmodifiable collection instance:
Collections.unmodifiableCollection(new ArrayList<>(map.values()));
回答2:
You must be updating the map
in another thread while you are iterating through col
. Both map#values
and Collections.unmodifiableCollection
return views of existing data structures, so what you are iterating over (and this is witnessed by your stacktrace) is the entry set of your map
.
来源:https://stackoverflow.com/questions/19726337/concurrentmodificationexception-in-unmodifiable-collection