Introduction
- In Java, iterators play an important role in traversing and manipulating collections. When it comes to handling concurrent changes while iterating, Java offers two main types of iterators, fail-fast and fail-safe. In this blog we'll explore the concept of fail-fast and fail-safe iterators, understands how they work, and provides code examples demonstrating their usage.
1. Fail-fast Iterator:
If we try to modify a collection while it is being iterated, fail-fast iterators throw a ConcurrentModificationException. This behaviour helps in detecting inconsistent modifications and ensures the integrity of data.
eg. ArrayList, Vector, HashSet, HashMap 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("Apple"); list.add("Banana"); list.add("Cherry"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Concurrent modification list.remove(0); } } }
Output:
Apple Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)at FailFastExample.main(FailFastExample.java:15)
2. Fail-saif Iterator:
Opposite to fail-fast iterators, fail-safe iterators do not raise a ConcurrentModificationException when a collection is modified while iterating.
It creates a copy of the list during the iteration process so it manipulates that copy hence no exception.
eg. CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap, etc
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { List<String> list = new CopyOnWriteArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Cherry"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Concurrent modification list.add("Mango"); } } }
Output:
Apple Banana Cherry
Fail-saif vs Fail-saif
Fail-fast | Fail-saif | |
Behavior on Modify | Throws a ConcurrentModificationException | No exception is thrown |
Performance | More efficient due to fewer overheads | Slightly less efficient due to copying or additional data structures |
Use Cases | Concurrent modification detection, data integrity | Iterate over collections that can be changed at the same time without interruptions |
Example | ArrayList, Vector, HashSet, HashMap etc. | CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap, et |
Conclusion
- Understanding the differences between fail-fast and fail-safe iterators in Java is important for writing robust and efficient code. You may assure data integrity and maintain consistent behavior throughout collection iteration by choosing the proper iterator type based on the requirements of your application.