👉 Short Answer:
If the collection is structurally modified outside the iterator (like calling
collection.remove()
directly), the iterator becomes invalid, and aConcurrentModificationException
will be thrown on the next iterator operation.
🧪 Example:
List<String> list = new ArrayList<>(List.of("A", "B", "C"));
Iterator<String> it = list.iterator();
list.remove("B"); // ❌ Structural modification outside the iterator
while (it.hasNext()) {
System.out.println(it.next()); // 💥 ConcurrentModificationException
}
⚠️ Why?
- The iterator captured the list’s
modCount
when it was created. - When you call
list.remove("B")
,modCount
is changed behind the iterator’s back. - When
it.next()
is called, it checksmodCount
and sees that it has changed → 💥 fail-fast exception.
✅ What’s the correct way to remove during iteration?
Use the iterator’s own remove()
method:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
it.remove(); // ✅ Safe
}
}
This way:
- The iterator is aware of the removal.
- The internal
modCount
is updated properly by the iterator itself. - No exception is thrown.
🧠 Summary
Operation | Result |
---|---|
collection.remove() during iteration | ❌ Unsafe — may cause ConcurrentModificationException |
iterator.remove() | ✅ Safe — iterator handles it correctly |
💬 Analogy
Imagine you’re reading a book (iterator
) while someone comes in and tears out a page (collection.remove()
) without telling you.
When you turn to that page → crash!
If you remove the page yourself (iterator.remove()
), you’re in control, so all is well.