Backend Development 7 min read

Avoid ConcurrentModificationException: Safe Ways to Remove Elements While Iterating in Java

This article explains why removing items from a Java List inside a foreach loop triggers java.util.ConcurrentModificationException and demonstrates three reliable alternatives—using Iterator.remove(), a forward for‑loop with index adjustment, and a reverse for‑loop—to safely modify collections during iteration.

macrozheng
macrozheng
macrozheng
Avoid ConcurrentModificationException: Safe Ways to Remove Elements While Iterating in Java

1. Common Mistake by Beginners

Many beginners try to remove elements from a

List

inside a foreach loop, which immediately throws

java.util.ConcurrentModificationException

.

<code>public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (String platform : platformList) {
        if (platform.equals("博客园")) {
            platformList.remove(platform);
        }
    }

    System.out.println(platformList);
}
</code>

The foreach construct is compiled to use an

Iterator

whose core methods are

hasNext()

and

next()

. During each

next()

call the iterator invokes

checkForComodification()

, which compares the collection’s internal

modCount

with an

expectedModCount

. Removing an element directly from the list changes

modCount

but not

expectedModCount

, causing the mismatch and the exception.

Therefore, foreach cannot be used for removal.

2. Use Iterator.remove() Method

Iterating with an explicit

Iterator

and calling its

remove()

safely updates

expectedModCount

.

<code>public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    Iterator<String> iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }

    System.out.println(platformList);
}
</code>
[CSDN, 掘金]

Each call to

iterator.remove()

resets

expectedModCount

to the current

modCount

, keeping them equal and preventing the exception.

3. Use Forward for Loop

Iterating with an index allows removal, but the index must be adjusted after each deletion.

<code>public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);
        if (item.equals("博客园")) {
            platformList.remove(i);
            i = i - 1;
        }
    }

    System.out.println(platformList);
}
</code>

After removing an element the list shrinks, so the next element shifts to the current index; decrementing

i

ensures the shifted element is not skipped.

<code>i = i - 1;
</code>

4. Use Reverse for Loop

Iterating from the end avoids index correction because removal does not affect the yet‑to‑visit elements.

<code>public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("掘金");

    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);
        if (item.equals("掘金")) {
            platformList.remove(i);
        }
    }

    System.out.println(platformList);
}
</code>

Since the loop proceeds backward, removing an element does not shift the indices of the remaining elements that are still to be processed.

JavaIteratorfor loopConcurrentModificationExceptionlist removal
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.