Please Explain FailFast iterator and FailSafe iterator along with examples for each.
In Java, iterators are used to traverse collections like lists, sets, and maps. There are two main types of iterators: Fail-Fast and Fail-Safe. They differ in how they handle concurrent modifications to the collection while iterating.
A Fail-Fast iterator immediately throws a ConcurrentModificationException
if it detects that the collection has been modified structurally (i.e., elements have been added or removed) after the iterator was created. This behavior is typically seen in the standard Java Collections Framework, such as ArrayList
, HashSet
, etc.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class FailFastExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
Iterator<String> iterator = list.iterator();
// Modifying the list while iterating
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
if (element.equals("B")) {
list.remove("B"); // This will cause ConcurrentModificationException
}
}
}
}
In this example, when we try to remove "B" from the list while iterating over it, a ConcurrentModificationException
will be thrown.
A Fail-Safe iterator, on the other hand, does not throw an exception when the collection is modified during iteration. Instead, it operates on a clone or snapshot of the collection at the time the iterator was created. This means that changes made to the collection after the iterator is created will not affect the iteration process.
Fail-Safe iterators are typically found in concurrent collections, such as CopyOnWriteArrayList
or ConcurrentHashMap
.
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class FailSafeExample {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
list.add("A");
list.add("B");
list.add("C");
// Using a fail-safe iterator
for (String element : list) {
System.out.println(element);
if (element.equals("B")) {
list.remove("B"); // This will not cause an exception
}
}
// The list still contains "A" and "C"
System.out.println("After modification: " + list);
}
}
In this example, we use a CopyOnWriteArrayList
, which allows us to remove "B" while iterating without throwing an exception. The iterator operates on a snapshot of the list, so the output will still include "A" and "C" after the modification.
ConcurrentModificationException
if the collection is modified during iteration. Common in standard collections like ArrayList
, HashSet
, etc.CopyOnWriteArrayList
and ConcurrentHashMap
.