All 15 Collections Framework questions
More in Collections Framework
Advertisement
Java › Collections Framework

What is the difference between fail-fast and fail-safe iterators in the Collections Framework, and which collections use each?

Intermediate

Answer

Fail-fast iterators (used by ArrayList, HashMap, HashSet, and most standard collections) detect concurrent structural modification during iteration (via an internal modCount field checked on each next() call) and immediately throw ConcurrentModificationException rather than risk undefined behavior -- fail-safe iterators (used by CopyOnWriteArrayList, ConcurrentHashMap) instead iterate over a stable snapshot (or tolerate concurrent modification gracefully without throwing), never throwing ConcurrentModificationException but potentially not reflecting the very latest modifications made during that iteration.
List<String> list = new ArrayList<>(List.of("a", "b", "c"));
for (String s : list) {
    if (s.equals("b")) {
        list.remove(s);  // throws ConcurrentModificationException! Fail-fast detects the structural change
    }
}

// Correct approach: use an Iterator's own remove() method
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("b")) it.remove();  // safe, iterator-aware removal
}
Real-world example A bug where removing an element from an ArrayList directly inside a for-each loop throws ConcurrentModificationException is fixed by switching to explicit Iterator.remove(), the correct fail-fast-aware way to modify a collection during iteration.

Common follow-ups: Why does fail-fast detection use "best-effort" language rather than being a strict guarantee?;What's the memory/performance trade-off of CopyOnWriteArrayList's fail-safe snapshot approach?