What causes ConcurrentModificationException and how do you avoid it?
It is thrown when a collection is structurally modified while you iterate over it, for example calling list.remove() inside a for-each loop. Remove through the Iterator, use removeIf, or iterate over a copy.
Explain it simply
Imagine the teacher is calling out names from the attendance list, and halfway through someone tears a row out of the page. The teacher loses their place. Java's iterators notice that the list changed behind their back and raise the alarm instead of giving wrong results.
Example
import java.util.*;
List<Integer> nums = new ArrayList<>(List.of(1, 2, 3, 4));
// for (int n : nums) { if (n % 2 == 0) nums.remove(Integer.valueOf(n)); } // throws CME
Iterator<Integer> it = nums.iterator();
while (it.hasNext()) {
if (it.next() % 2 == 0) it.remove(); // safe removal
}
System.out.println(nums); // prints: [1, 3]
nums.removeIf(n -> n > 2); // also safe
System.out.println(nums); // prints: [1]What to say in the interview
"ArrayList's iterator is fail-fast: it records a modCount when created and checks it on each next(). If the list is changed by anything other than that iterator, the counts differ and it throws ConcurrentModificationException. It is a best-effort bug detector, not a thread-safety feature. I avoid it with iterator.remove(), removeIf, or by collecting items to remove, or by using CopyOnWriteArrayList in multi-threaded reads."
Common mistakes
- Thinking it only happens with threads. A single thread triggers it easily.