Iterator vs ListIterator

In this tutorial we will learn about the difference between Iterator and ListIterator . We will also look at the examples of Iterator and ListIterator one by one. We have already discussed different type of iterators  i.e fail-fast iterator and fail-safe iterator.

Difference between Iterator and ListIterator in Java with Example
 
1. Traversal Direction  :  ListIterator allows the programmers to iterate the list objects in both directions i.e forward as well as backward direction using previous() and next() method.
Iterator can be used to  iterate the list,map and set object in one direction i.e forward.

2.  Set and Map implemented Objects Traversal : ListIterator can be used to traverse List object only . But Iterator can be used to traverse Map, List and Set implemented objects.

for example
// ListIterator object is created
ListIterator listIteratorObject = List.listIterator();
// Iterator object is created
Iterator  iteratorObject  = List.iterator();

3. Add or Set operation at any index : According to ListIterator Oracle docs,
ListIterator can modify the list  during iteration using add(E e) , remove() or set(E e).
Iterator can not add the element during traversal but they can remove the element from the underlying collection during the iteration as they only consist of remove() method. There is no add(E e) and set(E e) method in Iterator.

4. Determine Iterator’s current position :  ListIterator can obtain the iterator’s current position in the list. Iterator’s current position during traversal can not be determined using Iterator.

5. Retrieve Index of the element : ListIterator can obtain the index of the elements using previousIndex(E e) or nextIndex(E e) methods. We can not obtain the index using Iterator as there is no such methods present.

Example of Iterator and ListIterator 

import java.util.Iterator;
import java.util.ListIterator;

public class IteratorListIteratorExample {
public static void main(String[] args) {

List listObject = new ArrayList();
listObject.add(“Alive is awesome”);
listObject.add(“Love yourself”);

ListIterator listIteratorObject = listObject.listIterator();
System.out.println(“ListIterator object output in forward direction:”);
System.out.println(“”);
while( listIteratorObject.hasNext() )
{
System.out.println(listIteratorObject.next());
}

System.out.println(“ListIterator object output in backward direction:”);
System.out.println(“”);
while( listIteratorObject.hasPrevious() )
{
System.out.println(listIteratorObject.previous());
}

List iteratorListObject = new ArrayList();

iteratorListObject.add(“Facebook”);
iteratorListObject.add(“Google”);
iteratorListObject.add(“Apple”);

Iterator javaHungryIterator = iteratorListObject.iterator();
System.out.println(“Iterator object output in forward direction:”);

while( javaHungryIterator.hasNext() )
{
System.out.println(javaHungryIterator.next());
}

}
}

Output :

ListIterator object output in forward direction:
Alive is awesome
Love yourself
ListIterator object output in backward direction:
Love yourself
Alive is awesome
Iterator object output in forward direction:
Facebook
Google
Apple

Similarities between Iterator and ListIterator in Java

1. Interfaces : Both Iterator and ListIterator are interfaces . ListIterator extends Iterator interface.

2. Collection Framework : Both Iterator and ListIterator are member of the Java Collection Framework.

3. Traversal : Both are used to iterate over the collection of objects .

4. Interfaces added to jdk : Both interfaces are added to the jdk in java 1.2

Recap : Difference between Iterator and ListIterator in Java with Example 

ListIterator Iterator
Traversal Direction Both , forward and backward Forward
Objects traversal List only Map, Set and List
Add and Set operations Allows both operations Not possible
Iterator’s current position Yes , can be determined Not possible.
Retrieve Index Yes Not possible

Fail Fast Vs Fail Safe Iterator In Java?

Difference between Fail fast and fail safe iterator  or  Fail fast vs Fail Safe iterator is one of those questions which are  used to test your knowledge about the topic Concurrency.

Before we discuss in detail about fail safe iterator and fail fast iterator in addition to  their comparison , we should understand the term Concurrent Modification .

What is Concurrent Modification ?

When one or more thread is iterating over the collection, in between, one thread changes the structure of the collection (either adding the element to the collection or by deleting the element in the collection or by updating the value at particular position in the collection) is known as Concurrent Modification

Difference between Fail Fast iterator and Fail Safe iterator

Fail fast Iterator

Fail fast iterator while iterating through the collection , instantly throws Concurrent Modification Exception if there is structural modification  of the collection . Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Fail-fast iterator can throw ConcurrentModificationException in two scenarios :

Single Threaded Environment
 
After the creation of the iterator , structure is modified at any time by any method other than iterator’s own remove method.
 
Multiple Threaded Environment

If one thread is modifying the structure of the collection while other thread is iterating over it .

According to  Oracle docs , the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

Interviewer : How  Fail  Fast Iterator  come to know that the internal structure is modified ?

Iterator read internal data structure (object array) directly . The internal data structure(i.e object array) should not be modified while iterating through the collection. To ensure this it maintains an internal  flag “mods” .Iterator checks the “mods” flag whenever it gets the next value (using hasNext() method and next() method). Value of mods flag changes whenever there is an structural modification. Thus indicating iterator to throw ConcurrentModificationException.

Fail Safe Iterator :

Fail Safe Iterator makes copy of the internal data structure (object array) and iterates over the copied data structure.Any structural modification done to the iterator affects the copied data structure.  So , original data structure remains  structurally unchanged .Hence , no ConcurrentModificationException throws by the fail safe iterator.

Two  issues associated with Fail Safe Iterator are :

1. Overhead of maintaining the copied data structure i.e memory.

2.  Fail safe iterator does not guarantee that the data being read is the data currently in the original data structure.

According to Oracle docs , fail safe iterator is ordinarily too costly, but may be more efficient than alternatives when traversal operations vastly outnumber mutations, and is useful when you cannot or don’t want to synchronize traversals, yet need to preclude interference among concurrent threads. The “snapshot” style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.The iterator will not reflect additions, removals, or changes to the list since the iterator was created. Element-changing operations on iterators themselves (remove(), set(), and add()) are not supported. These methods throw UnsupportedOperationException.

Example of Fail Fast Iterator and Fail Safe Iterator

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class FailFastExample
{
    
    
    public static void main(String[] args)
    {
        Map<String,String> premiumPhone = new HashMap<String,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");
        
        Iterator iterator = premiumPhone.keySet().iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(premiumPhone.get(iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
        
    }
    
}

Output :

iPhone 
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$KeyIterator.next(Unknown Source)
        at FailFastExample.main(FailFastExample.java:20)

Fail Safe Iterator Example :

import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;


public class FailSafeExample
{
    
    
    public static void main(String[] args)
    {
        ConcurrentHashMap<String,String> premiumPhone = 
                                     new ConcurrentHashMap<String,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");
        
        Iterator iterator = premiumPhone.keySet().iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(premiumPhone.get(iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
        
    }
    
}

Output :

S5
HTC one
iPhone

Recap : Difference between Fail Fast Iterator and Fail Safe Iterator

Fail Fast Iterator Fail Safe Iterator
Throw ConcurrentModification Exception Yes No
Clone object No Yes
Memory Overhead No Yes
Examples HashMap,Vector,ArrayList,HashSet CopyOnWriteArrayList,
ConcurrentHashMap