ConcurrentModificationException signals an unsupported structural change during iteration. Enhanced for-each syntax uses an iterator, so adding or removing directly from a non-concurrent collection can fail fast on the next iterator operation. section 8.8
List<String> list = new ArrayList<>(List.of("a", "b", "c"));
for (String s : list) {
System.out.println(s);
if (s.equals("b")) {
list.add("x");
}
}
This minimal example adds to a list inside enhanced for-each iteration, exposing the faulty pattern. section 8.8
Standard collections track a modCount value. An iterator copies it when created; next() compares the copy with the collection’s current value and throws when they differ. This fail-fast check avoids continuing with uncertain visibility of later changes. section 8.8
Avoid the mistake with these practical alternatives:
- Modify through the iterator used for iteration when the operation is supported. section 8.8
- Use an indexed loop when direct list modification is intentional, while recognizing that classic loops are fragile. section 8.8
- Iterate over a copy when the original collection must be modified during processing. section 8.8
