Removing Elements from a Collection in Java: How to Avoid ConcurrentModificationException

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

"I want to remove an element from a list in a loop — and I get ConcurrentModificationException." Sound familiar?

\n

If you've ever written Java code and tried to remove an element from an ArrayList or HashMap during iteration (for example, in a for-each loop), you've likely seen this scary red exception. It pops up at the worst possible moment, as if Java is telling you: "Hey, what are you doing? Don't touch the collection while I'm iterating over it!"

\n\n

This question has gathered thousands of views on Stack Overflow. And it's no coincidence: the problem seems simple, but under the hood lies a whole layer of optimizations and multithreading nuances. In this article, we'll break down how to correctly remove objects from a collection in a Java loop without causing ConcurrentModificationException, while maintaining performance.

\n\n

Let's go!

\n\n

Why does ConcurrentModificationException occur?

\n

The short answer: fail-fast iterators. Most collections from the Java Collections Framework (ArrayList, HashSet, HashMap, etc.) use an internal modification counter (modCount). When you create an iterator, it remembers the current value of modCount. Each time next() is called, the iterator checks whether the collection has been modified externally (via the collection's own add() or remove() methods). If the counters don't match, the exception is thrown.

\n\n

Example code that is guaranteed to fail:

\n
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));\nfor (String item : list) {\n    if ("B".equals(item)) {\n        list.remove(item); // ConcurrentModificationException!\n    }\n}\n
\n

Why? Because for-each implicitly uses an iterator, while list.remove() modifies modCount directly, bypassing the iterator. The iterator does not forgive this.

\n\n

Method #1: Use Iterator.remove() — the classic approach

\n

The simplest and most correct way is to explicitly take the iterator into your own hands and call its remove() method. This method synchronizes the iterator's internal counter with the collection.

\n
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));\nIterator<String> iterator = list.iterator();\nwhile (iterator.hasNext()) {\n    String item = iterator.next();\n    if ("B".equals(item)) {\n        iterator.remove(); // Safe!\n    }\n}\nSystem.out.println(list); // [A, C, D]\n
\n

Pros: safe, works for all collections that support iterators. Cons: slightly verbose. For simple filtering, more modern approaches can be used.

\n\n

Method #2: Collection.removeIf() — modern and elegant

\n

Starting with Java 8, most collections have a removeIf(Predicate filter) method. This is the most concise way to remove elements based on a condition.

\n
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));\nlist.removeIf(item -> "B".equals(item));\nSystem.out.println(list); // [A, C, D]\n
\n

Internally, removeIf uses an iterator (or a direct pass with index preservation), so no ConcurrentModificationException will occur. This is the recommended approach for simple cases.

\n

Performance: For ArrayList, the removeIf method runs in O(n), but does so efficiently — it shifts elements in a single pass, rather than removing them one by one (which would be O(n²)).

\n\n

Method #3: Reverse index traversal (for List)

\n

If for some reason you cannot use an iterator (for example, you need to modify multiple elements simultaneously or you are working with legacy code), you can traverse the list in reverse order using a regular for loop with an index.

\n
List<String> list = new A                

Blogs

Book Recommendations