Iterator is a universal iterator as we can apply it to any Collection object. By using Iterator, we can perform both read and remove operations. It is improved version of Enumeration with additional functionality of remove-ability of a element.
Iterator object can be created by calling iterator() method present in Collection interface.
Iterator has four method for traversal. hasNext(), next(), remove() and forEachRemainin()
ListIterator is only applicable for List collection implemented classes like arraylist, linkedlist etc. It provides bi-directional iteration.
Fail-Fast systems abort operation as-fast-as-possible exposing failures immediately and stopping the whole operation.
Fail-fast iterators in Java don’t play along when the underlying collection gets modified.
Please see demonstration of fail fast iterator on below github link
https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/collections/iterator/example1
Lets consider an example of using an Iterator over an ArrayList
1. The ArrayList extends a class known as a AbstractList and it also implements List
2. The AbstractList contains in itself a protected transient int variable named modCount
3. As we add and remove elements, this variable is accordingly updated
4. When we call the iterator() on the ArrayList, it internally creates an instance of a Subclass Itr (implementation of Iterator and an inner class to AbstractList) which stores the value of modCount (at that point when iterator() was called) in a local Variable named expectedModCount
5. So the iterator before performing any action, compares the expectedModCount to the ModCount and accordingly actions
1. The CopyOnWriteArrayList does not extend the AbstractList but directly implements List
2. When the iterator() method on this collection is called, it created a new instance of an COWIterator (inner class to CopyOnWriteArrayList and implementation of ListIterator) and stores a copy (snapshot at that point of time) of the underlying array i.e. Object[] array which the ArrayList uses internally to store the elements
3. Then all operations of the iterator are performed on this snapshot and not on the actual collection
Iterator object can be created by calling iterator() method present in Collection interface.
Iterator has four method for traversal. hasNext(), next(), remove() and forEachRemainin()
ListIterator is only applicable for List collection implemented classes like arraylist, linkedlist etc. It provides bi-directional iteration.
ListIterator must be used when we want to enumerate elements of List. This cursor has more functionality(methods) than iterator.
ListIterator object can be created by calling listIterator() method present in List interface.
ListIterator has six additional methods for traversal. hasPrevious(). previous(), add(E e), nextIndex(), previousIndex() and set(E e)
ListIterator has six additional methods for traversal. hasPrevious(). previous(), add(E e), nextIndex(), previousIndex() and set(E e)
Fail-Fast Iterators
Fail-Fast systems abort operation as-fast-as-possible exposing failures immediately and stopping the whole operation.
Fail-fast iterators in Java don’t play along when the underlying collection gets modified.
- Collections maintain an internal counter called modCount. Each time an item is added or removed from the Collection, this counter gets incremented.
- When iterating, on each next() call, the current value of modCount gets compared with the initial value. If there’s a mismatch, it throws ConcurrentModificationException which aborts the entire operation.
- Default iterators for Collections from java.util package such as ArrayList, HashMap, etc. are Fail-Fast.
The Fail-Fast behavior isn’t guaranteed to happen in all scenarios as it’s impossible to predict behavior in case of concurrent modifications. These iterators throw ConcurrentModificationException on a best effort basis.
If during iteration over a Collection, an item is removed using Iterator‘s remove() method, that’s entirely safe and doesn’t throw an exception.However, if the Collection‘s remove() method is used for removing an element, it throws an exception.
Please see demonstration of fail fast iterator on below github link
https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/collections/iterator/example1
Lets consider an example of using an Iterator over an ArrayList
1. The ArrayList extends a class known as a AbstractList and it also implements List
2. The AbstractList contains in itself a protected transient int variable named modCount
3. As we add and remove elements, this variable is accordingly updated
4. When we call the iterator() on the ArrayList, it internally creates an instance of a Subclass Itr (implementation of Iterator and an inner class to AbstractList) which stores the value of modCount (at that point when iterator() was called) in a local Variable named expectedModCount
5. So the iterator before performing any action, compares the expectedModCount to the ModCount and accordingly actions
Fail-Safe Iterators
These iterators create a clone of the actual Collection and iterate over it. If any modification happens after the iterator is created, the copy still remains untouched. Hence, these Iterators continue looping over the Collection even if it’s modified.
However, it’s important to remember that there’s no such thing as a truly Fail-Safe iterator. The correct term is Weakly Consistent.
That means, if a Collection is modified while being iterated over, what the Iterator sees is weakly guaranteed. This behavior may be different for different Collections and is documented in Javadocs of each such Collection.
The Fail-Safe Iterators have a few disadvantages, though:
- One disadvantage is that the Iterator isn’t guaranteed to return updated data from the Collection, as it’s working on the clone instead of the actual Collection.
- Another disadvantage is the overhead of creating a copy of the Collection, both regarding time and memory.
Iterators on Collections from java.util.concurrent package such as ConcurrentHashMap, CopyOnWriteArrayList, etc. are Fail-Safe in nature.
Please see demonstration of fail safe iterator on below github link
https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/collections/iterator/example2
Lets consider an example of CopyOnWriteArrayList
2. When the iterator() method on this collection is called, it created a new instance of an COWIterator (inner class to CopyOnWriteArrayList and implementation of ListIterator) and stores a copy (snapshot at that point of time) of the underlying array i.e. Object[] array which the ArrayList uses internally to store the elements
3. Then all operations of the iterator are performed on this snapshot and not on the actual collection