Ad Space — Top Banner

ConcurrentModificationException

Java Programming Language

Severity: Moderate

What Does This Error Mean?

A ConcurrentModificationException means your code tried to change a collection (like a list or map) while it was being iterated — looped over. Java detects this and throws an error to protect you from unpredictable results. The fix is to either use a different loop approach, collect changes and apply them after the loop, or use a thread-safe collection.

Affected Models

  • Java 8
  • Java 11
  • Java 17
  • Java 21
  • All Java versions

Common Causes

  • Calling list.remove() or list.add() inside a for-each loop on the same list
  • Modifying a collection in one thread while another thread is iterating over it
  • Removing items from a Map's entry set while looping through it with for-each
  • Calling a method inside the loop that internally modifies the collection being looped
  • Using an iterator-based loop but calling the list's remove() method instead of the iterator's remove() method

How to Fix It

  1. If you need to remove items while looping, use an explicit Iterator instead of a for-each loop. Call iterator.remove() to remove the current item safely.

    Example: Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = it.next(); if (shouldRemove(s)) it.remove(); }

  2. Another safe approach: collect the items you want to remove into a separate list during the loop, then call originalList.removeAll(toRemove) after the loop finishes.

    This is often the most readable fix: first pass to collect, second pass to remove. Very clean and easy to understand.

  3. In Java 8 and newer, use the removeIf() method on your collection. This removes all items matching a condition in one line without any ConcurrentModificationException risk.

    Example: list.removeIf(item -> item.isExpired()); — cleaner than any manual loop approach.

  4. If the error happens across multiple threads, use a thread-safe collection like CopyOnWriteArrayList or Collections.synchronizedList(). These allow iteration and modification from different threads safely.

    CopyOnWriteArrayList creates a copy of the list for each write operation — iteration sees the original, so no conflict. Good for read-heavy scenarios.

  5. Use a traditional index-based for loop (for int i = 0; i < list.size(); i++) when removing items, but iterate backwards (from high to low index) so that removing an item does not shift the indexes you have not visited yet.

    Backwards example: for (int i = list.size() - 1; i >= 0; i--) { if (shouldRemove(list.get(i))) list.remove(i); }

When to Call a Professional

ConcurrentModificationException is always a fixable code logic issue. The fix is usually straightforward: change how you remove items during iteration. The stack trace shows which line triggered the error — go there first.

Frequently Asked Questions

Does ConcurrentModificationException only happen with multiple threads?

No — it most commonly happens in a single thread. The name is misleading. It just means 'the collection was modified while an iterator was active' — whether that was from another thread or from your own code inside the same loop.

Why does Java not just allow modification during iteration and handle it automatically?

Because there is no 'correct' behavior to default to. If you add or remove items mid-loop, should the loop see the new items? Skip the removed one? The answer depends entirely on what your program is trying to do. Java fails fast and loudly so you are forced to make that choice yourself.

What is the difference between iterator.remove() and list.remove()?

iterator.remove() removes the item the iterator just returned — it tells the iterator what happened so it can stay in sync. list.remove() removes an item without telling the iterator, causing the structure to change underneath the iterator. Always use iterator.remove() when inside an iterator loop.