Question

If I use Iterator.remove(), everything is fine. If I use ArryaList.remove(), I always receive the error java.util.ConcurrentModificationException.

Can anyone point out the reason?

Was it helpful?

Solution

Basically because that's how it's designed to work. If you delete an element from the list, the iterator doesn't know about it, and when it tries to access another element in the list, the list has changed and an error is raised. But if you remove an element through the iterator, then the itertor knows about the removal, makes the appropriate adjustment to its data structures, and continues.

OTHER TIPS

The javadocs say it all:

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

You're modifying a collection and iterating over it at the same time.

So exactly from docs

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Have look at Class ConcurrentModificationException

If you need to remove an element while you are iterating through a list then you should always use iterator.

e.g.

List<String> list = //...
//...
Iterator<String> iter = list.iterator();

while(iter.hasNext()) {
    String str = itr.next();
    //...
    if(/* ... */) {
        iter.remove(str);
    }
}

That's the safest way of removing an element from a list while you are iterating through the list.

Note: You should not do something as follows:

List<String> list = //...
//...
for(String str : list) {
    if(/* ... */) {
        list.remove(); // <-- should not do this
    }
}

Where mostly you will end up in a ConcurrentModificationException. That enhanced for loop uses the iterator under the hood. And you are manually removing the element from the list instead of going through the iterator. That's why you get that exception.

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