Question

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.

Was it helpful?

Solution

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()));

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top