👉 Short Answer:
If the collection is structurally modified outside the iterator (like calling
collection.remove()directly), the iterator becomes invalid, and aConcurrentModificationExceptionwill 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
modCountwhen it was created. - When you call
list.remove("B"),modCountis changed behind the iterator’s back. - When
it.next()is called, it checksmodCountand 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
modCountis 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.