Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

ConcurrentModificationException in Java — Fix (2026) | Tutorials Logic

What is This Error?

The ConcurrentModificationException is thrown when a collection is modified while it is being iterated using an iterator or enhanced for-each loop. Java's fail-fast iterators detect structural modifications and throw this exception to prevent unpredictable behavior.

Common Causes

  • Adding or removing elements from a list while iterating with for-each
  • Modifying a collection in a multi-threaded environment without synchronization
  • Calling list.remove() instead of iterator.remove() during iteration
  • Modifying a Map's entrySet while iterating over it
  • Nested iteration where inner loop modifies the outer collection

Quick Fix (TL;DR)

Quick Solution
// ❌ Problem
for (String item : list) {
    if (item.equals("remove")) list.remove(item); // ConcurrentModificationException!
}

// ✅ Solution 1: Use Iterator
Iterator it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("remove")) it.remove(); // Safe!
}

// ✅ Solution 2: removeIf (Java 8+)
list.removeIf(item -> item.equals("remove"));

Common Scenarios & Solutions

Scenario 1: Removing During For-Each

Problem
List numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Integer num : numbers) {
    if (num % 2 == 0) {
        numbers.remove(num); // ❌ ConcurrentModificationException!
    }
}
Solution
List numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

// ✅ Option 1: removeIf (cleanest)
numbers.removeIf(num -> num % 2 == 0);

// ✅ Option 2: Iterator
Iterator it = numbers.iterator();
while (it.hasNext()) {
    if (it.next() % 2 == 0) it.remove();
}

// ✅ Option 3: Collect to remove list
List toRemove = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());
numbers.removeAll(toRemove);

// ✅ Option 4: Stream filter (creates new list)
numbers = numbers.stream()
    .filter(n -> n % 2 != 0)
    .collect(Collectors.toList());

Scenario 2: Multi-threaded Modification

Solution
// ✅ Use CopyOnWriteArrayList for thread-safe iteration
List list = new CopyOnWriteArrayList<>(Arrays.asList("a", "b", "c"));
for (String s : list) {
    list.add("d"); // Safe — iterates over snapshot
}

// ✅ Or use synchronized block
List syncList = Collections.synchronizedList(new ArrayList<>());
synchronized (syncList) {
    for (String s : syncList) {
        // Safe iteration
    }
}

Scenario 3: Modifying Map During Iteration

Problem
Map map = new HashMap<>();
map.put("a", 1); map.put("b", 2); map.put("c", 3);
for (Map.Entry entry : map.entrySet()) {
    if (entry.getValue() < 2) map.remove(entry.getKey()); // ❌ CME!
}
Solution
// ✅ Use Iterator on entrySet
Iterator> it = map.entrySet().iterator();
while (it.hasNext()) {
    if (it.next().getValue() < 2) it.remove();
}

// ✅ Or use entrySet().removeIf (Java 8+)
map.entrySet().removeIf(e -> e.getValue() < 2);

Best Practices to Avoid This Error

  • Use removeIf() - Cleanest way to remove elements conditionally (Java 8+)
  • Use Iterator.remove() - Safe removal during iteration
  • Collect then remove - Build a removal list, then call removeAll()
  • Use CopyOnWriteArrayList - For thread-safe iteration with modifications
  • Use Stream.filter() - Creates a new collection without modifying the original
  • Use ConcurrentHashMap - Thread-safe map that allows concurrent modification
  • Avoid modifying collections in nested loops - Use separate data structures

Related Errors

Key Takeaways
  • ConcurrentModificationException is thrown when a collection is modified during iteration
  • Use removeIf() for the cleanest conditional removal in Java 8+
  • Use Iterator.remove() for safe removal during manual iteration
  • Collect elements to remove first, then call removeAll() after iteration
  • Use CopyOnWriteArrayList or ConcurrentHashMap for thread-safe concurrent access
  • Stream.filter() creates a new collection without modifying the original

Frequently Asked Questions


Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.