java.util.ConcurrentModificationException

This post shows show to solve the problem of java.util.ConcurrentModificationException for ArrayList.

The error message looks like the following:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	...
	...

The Problem

You may want to iterate through an ArrayList, and delete some element under some condition. For example, the following code looks reasonable:

import java.util.ArrayList;
import java.util.List;
 
public class AddRemoveListElement {
 
	public static void main(String args[]) {
		List<String> list = new ArrayList<String>();
		list.add("A");
		list.add("B");
 
		for (String s : list) {
			if (s.equals("B")) {
				list.remove(s);
			}
		}
	}
}

Output:
java-util-concurrentModificationException

Solution 1

Iterator can be used to solve this problem. Iterators allow the caller to remove elements from the underlying collection during the iteration.

Iterator<String> iter = list.iterator();
while(iter.hasNext()){
	String str = iter.next();
      if( str.equals("B") )
      {
        iter.remove();
      }
}

Solution 2

Instead of ArrayList, CopyOnWriteArrayList can be used to solve the problem. CopyOnWriteArrayList is a thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.

public static void main(String args[]) {
	List<String> list = new CopyOnWriteArrayList<String>();
	list.add("A");
	list.add("B");
 
	for (String s : list) {
		if (s.equals("B")) {
			list.remove(s);
		}
	}
}

How about other Collection types?

public static void main(String args[]) {
	Set<String> set = new HashSet<String>();
	set.add("A");
	set.add("B");
 
	for (String s : set) {
		if (s.equals("B")) {
			set.remove(s);
		}
	}
}
public static void main(String args[]) {
	LinkedList<String> llist = new LinkedList<String>();
	llist.add("A");
	llist.add("B");
 
	for (String s : llist) {
		if (s.equals("B")) {
			llist.remove(s);
		}
	}
}

The above code is fine, because they do not use array as the underlining data structure.

Category >> Collections  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • abdulkerim

    I solved with CopyOnWriteArrayList. thanks so much

  • XeNeX

    This is not true:
    “The above code is fine, because they do not use array as the underlining data structure.”
    In each of collection is a counter which indicate if collection has been changed (it structure – added or removed element not replaced). If structure of collection will change we will get exception 🙂

  • Bibhudutta Pradhan

    I added 2 more elements into the LinkedList and let the remaining codes unchanged.
    It did throw “java.util.ConcurrentModificationException”
    why ?

  • Akram Ahmad

    Your suggestion to use “CopyOnWriteArrayList” is brilliantly helpful. I’m exploring it’s use, and it is looking good so far 🙂 Plus I need to crack open my well-worn copy of Brian Goetz’s classic work on concurrency (JCIP) for a refresher…. Thank you!