How to Avoid/Fix ConcurrentModificationException while looping over ArrayList in Java [Example] (original) (raw)

Apart from the NullPointerException and ClassNotFoundException, ConcurrentModificationException is another nightmare for Java developers. What makes this error tricky is the word concurrent, which always mislead Java programmers that this exception is coming because multiple threads are trying to modify the collection at the same time. Then begins the hunting and debugging, they spent countless hours to find the code which has the probability of concurrent modification. While in reality, ConcurrentModficationException can also come in a single-threaded environment.

To give you an example, just loop over a list using for loop and try to remove one element, you will get the ConcurrentModificatoinExcetpion? Why? because you broke the rule of not modifying a Collection during iteration.

How does Java know to throw ConcurrentModificationExeption? It uses a transient variable called modCount, which keeps track of how many times a list is modified structurally. Structural modifications are those that change the size of the list, which may affect the progress of iteration and may yield incorrect results.

Both Iterator and ListIterator use this field to detect unexpected change. Other methods of List which structurally modify List also use this method like add(), remove().

Problem: loop over an ArrayList and remove selected elements, but remove() is throwing "Exception in thread "main" java.util.ConcurrentModificationException".

Cause: The real cause of ConcurrentModfiicationException is inconsistent modCount. When you are iterating over ArrayList then Iterator's next() method keep track of modCount. If you modify the collection by adding or removing elements then modCount will change and it will not match with the expected modCount, hence Iterator will throw ConcurrentModificationException.

Here is the code snippet from the hasNext() method which shows there is check for modCount:

public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }

Now if you check this checkForComodification() method, you will find what I just said:

final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }

Solution: Use Iterator if you are doing it on the single-threaded environment, otherwise use concurrent collection classes like CopyOnWriteArrayList to remove elements while you are looping over it.

Solving ConcurrentModificationException while Iterating over ArrayList in Java

Here is the Java program to demonstrate one scenario where you get the ConcurrentModificationException even if just one thread is modifying the ArrayList. In this example, we are looping over ArrayList using advanced for loop and removing selected elements, but because we are using ArrayList's remove() method.

import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List;

/**

}

Output : list of phones: [iPhone 6S, iPhone 6, iPhone 5, Samsung Galaxy 4, Lumia Nokia] list after removal: [Samsung Galaxy 4, Lumia Nokia]

If you uncomment the commented code in the first loop and second loop, you will get the following exception:

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

because we are using ArrayList's remove() method. In the second example, we have used the remove() method of Iterator and that's why we are successfully able to delete selected elements from the ArrayList without ConcurrentModificationException.

How to Fix ConcurrentModficiationException in Java?

Here is a summary of important points about solving ConcurrentModificationException while looping or Iterating over ArrayList in Java :

How to solve ConcurrentModificationException in Java

That's all about how to deal with ConcurrentModificationException in Java. The biggest thing to learn and remember is that this error can come even if you have just one thread modifying collection like removing elements while looping over the list.

So, while the name suggest concurrentModification it doesn't always mean that multiple threads are modifying the Collection or ArrayList at the same time. The simplest scenarios when this error comes when you are iterating over an ArrayList in Java and then using ArrayList.remove() method to remove objects.

Same is true when you sue the for each loop of Java 5 to loop over Collection or List as it internally uses Iterator. You can fix ConcurrentModificationException by changing your code and instead of using ArrayList.remove() method just use Iterator.remove() method in Java.

Related troubleshooting guides
Here are some handy Java tips to solve some common errors and exceptions in Java: