Java ListIterator – ListIterator in Java

Filed Under: Java

As we know Java has four cursors: Enumeration, Iterator, ListIterator, and Spliterator. We have already discussed Enumeration and Iterator cursors in my previous post. Before going through this post, please go through my previous post at: Java Iterator.

In this post, we will discuss about third Java cursor: ListIterator.

Java ListIterator

Like Iterator, ListIterator is a Java Iterator, which is used to iterate elements one-by-one from a List implemented object.

  • It is available since Java 1.2.
  • It extends Iterator interface.
  • It is useful only for List implemented classes.
  • Unlike Iterator, It supports all four operations: CRUD (CREATE, READ, UPDATE and DELETE).
  • Unlike Iterator, It supports both Forward Direction and Backward Direction iterations.
  • It is a Bi-directional Iterator.
  • It has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next().

NOTE:- What is CRUD operations in Collection API?

  • CREATE: Adding new elements to Collection object.
  • READ: Retrieving elements from Collection object.
  • UPDATE: Updating or setting existing elements in Collection object.
  • DELETE: Removing elements from Collection object.

Java ListIterator Class Diagram

In Java, ListIterator is an interface in Collection API. It extends Iterator interface. To support Forward and Backward Direction iteration and CRUD operations, it has the following methods. We can use this Iterator for all List implemented classes like ArrayList, CopyOnWriteArrayList, LinkedList, Stack, Vector, etc.

Java ListIterator

We will explore these methods in-depth with some useful methods in the coming sections.

Java ListIterator Methods

Java ListIterator interface has the following Methods.

  • void add(E e): Inserts the specified element into the list.
  • boolean hasNext(): Returns true if this list iterator has more elements when traversing the list in the forward direction.
  • boolean hasPrevious(): Returns true if this list iterator has more elements when traversing the list in the reverse direction.
  • E next(): Returns the next element in the list and advances the cursor position.
  • int nextIndex(): Returns the index of the element that would be returned by a subsequent call to next().
  • E previous(): Returns the previous element in the list and moves the cursor position backwards.
  • int previousIndex(): Returns the index of the element that would be returned by a subsequent call to previous().
  • void remove(): Removes from the list the last element that was returned by next() or previous().
  • void set(E e): Replaces the last element returned by next() or previous() with the specified element.

We will explore these methods one-by-one with useful examples in the coming sections.

Java ListIterator Basic Example

In this section, we will discuss some ListIterator methods with some examples. First, we need to understand about how to get this iterator object.

How to get ListIterator?


ListIterator<E> listIterator()

It returns a list iterator over the elements in this list.

Example:-


import java.util.*;

public class ListIteratorDemo 
{
  public static void main(String[] args) 
  {
	List<String&gt names = new LinkedList<>();
	names.add("Rams");
	names.add("Posa");
	names.add("Chinni");
		
	// Getting ListIterator
	ListIterator<String&gt namesIterator = names.listIterator();
	
	// Traversing elements
	while(namesIterator.hasNext()){
	   System.out.println(namesIterator.next());			
	}	

	// Enhanced for loop creates Internal Iterator here.
	for(String name: names){
	   System.out.println(name);			
	}	
  }
}

Output:-


Rams
Posa
Chinni

ListIterator Bi-Directional Iteration Example

In section, we will explore how ListIterator’s methods work to perform Forward Direction and Backward Direction iterations.


import java.util.*;

public class BiDirectinalListIteratorDemo 
{
	public static void main(String[] args) 
	{
		List<String&gt names = new LinkedListt<>();
		names.add("Rams");
		names.add("Posa");
		names.add("Chinni");
		
		// Getting ListIterator
		ListIterator<String&gt listIterator = names.listIterator();
		
		// Traversing elements
		System.out.println("Forward Direction Iteration:");
		while(listIterator.hasNext()){
			System.out.println(listIterator.next());			
		}	
		
		// Traversing elements, the iterator is at the end at this point
		System.out.println("Backward Direction Iteration:");
		while(listIterator.hasPrevious()){
			System.out.println(listIterator.previous());			
		}
	}
}

Output:-


Forward Direction Iteration:
Rams
Posa
Chinni
Backward Direction Iteration:
Chinni
Posa
Rams

Types of Java Iterators

As we know Java has four cursors: Enumeration, Iterator, ListIterator, and Spliterator. We can categorize them into two main types as shown below:

  • Uni-Directional Iterators
  • They are Cursors which supports only Forward Direction iterations. For instance, Enumeration, Iterator, etc. are Uni-Directional Iterators.

  • Bi-Directional Iterators
  • They are Cursors which supports Both Forward Direction and Backward Direction iterations. For instance, ListIterator is Bi-Directional Iterator.

java cursor types

How Java ListIterator Works Internally?

As we know, Java ListIterator works in both directions that mean it works in the forward direction as well as backward direction. It is a Bi-directional Iterator. To support this functionality, it has two sets of methods.

  • Forward Direction Iteration methods
  • We need to use the following methods to support Forward Direction Iteration:

    1. hasNext())
    2. next()
    3. nextIndex()
  • Backward Direction Iteration methods
  • We need to use the following methods to support Backward Direction Iteration:

    1. hasPrevious()
    2. previous()
    3. previousIndex()

In my previous post, we have already discussed how an Iterator works internally in forwarding Direction at “How Java Iterator Works Internally?” section. Even ListIterator also works in that same way. If you want go through my previous post, please click here: Java Iterator.

In this section, we will discuss how ListIterator works in Backward Direction.

Let us take the following LinkedList object to understand this functionality.


List<String> names = new LinkedList<>();
names.add("E-1");
names.add("E-2");
names.add("E-3");
.
.
.
names.add("E-n");

Now create a ListIterator object on LinkedList as shown below:


ListIterator<String> namesIterator = names.listLterator();

Let us assume “namesIterator” ListIterator looks like below:

List Iterator in Java

Here ListIterator’s Cursor is pointing to the before the first element of the List. Now we run the following code snippet in the while loop.


namesIterator.hasNext();
namesIterator.next();

When we run the above code snippet in the while loop, ListIterator’s Cursor points to the last element in the LinkedList.

ListIterator backward traversing

Then we can run the following code snippet to start traversing from the end to the start.


namesIterator.hasPrevious();
namesIterator.previous();

List Iterator hasPrevious

When we run the above code snippet, ListIterator’s Cursor points to the “Last but one” element in the List as shown in the above diagram. Do this process to reach the ListIterator’s Cursor to the first element of the LinkedList.

ListIterator cursor diagram

After reading the first element, if we run the below code snippet, it returns “false” value.


namesIterator.hasPrevious();

ListIterator hasNext

As ListIterator’s Cursor points to the before the first element of the LinkedList, hasPrevious() method returns a false value.

After observing all these diagrams, we can say that Java ListIterator supports Both Forward Direction and Backward Direction Iterations as shown in the below diagrams. So it is also known as Bi-Directional Cursor.

Forward Direction ListIterator

List Iterator Methods

Backward Direction ListIterator

ListIterator traversing

Advantages of ListIterator

Unlike Iterator, ListIterator has the following advantages:

  • Like Iterator, it supports READ and DELETE operations.
  • It supports CREATE and UPDATE operations too.
  • That means, it supports CRUD operations: CREATE, READ, UPDATE and DELETE operations.
  • It supports both Forward direction and Backward direction iteration. That means it’s a Bi-Directional Java Cursor.
  • Method names are simple and easy to use them.

Limitations of ListIterator

Compare to Iterator, Java ListIterator has many advantages. However, it still have the following some limitations.

  • It is an Iterator only List implementation classes.
  • Unlike Iterator, it is not applicable for whole Collection API.
  • It is not a Universal Java Cursor.
  • Compare to Spliterator, it does NOT support Parallel iteration of elements.
  • Compare to Spliterator, it does NOT support better performance to iterate large volume of data.

Similarities between Iterator and ListIterator

In this section, we will discuss about Similarities between Java two Cursors: Iterator and ListIterator.

  • Bother are introduced in Java 1.2.
  • Both are Iterators used to iterate Collection or List elements.
  • Both supports READ and DELETE operations.
  • Both supports Forward Direction iteration.
  • Both are not Legacy interfaces.

Differences between Iterator and ListIterator

In this section, we sill discuss differences between Java Two Iterators: Iterator and ListIterator.

Iterator ListIterator
Introduced in Java 1.2. Introduced in Java 1.2.
It is an Iterator for whole Collection API. It is an Iterator for only List implemented classes.
It is an Universal Iterator. It is NOT an Universal Iterator.
It supports only Forward Direction Iteration. It supports both Forward and Backward Direction iterations.
It’s a Uni-Directional Iterator. It’s a Bi-Directional Iterator.
It supports only READ and DELETE operations. It supports all CRUD operations.
We can get Iterator by using iterator() method. We can ListIterator object using listIterator() method.

That’s all of about ListIterator in Java. I hope these Java ListIterator theories and examples will help you in getting started with ListIterator programming.

Reference: ListIterator API Doc

Comments

  1. Vikas Kumar says:

    The explanation of ListIterator is wrong at ListIterator.hasPrevious() section.
    You are telling that after executing

    namesIterator.hasPrevious();
    namesIterator.previous();
    The cursor will point to last element in the linked list but it is wrong.
    When you execute this statement you gill get runTimeException as NoSuchElementException.
    This is because after calling listIterator() function, the cursor will point at the first element of the list.
    If we want the cursor to point to the last element of List, explicitly we have to iterate throughout the list to reach end of the list, after that we would be able to point to last element of list.

  2. Praveen says:

    Hi
    The below line of code does not go infinite loop. Can anyone explain why?
    ArrayList arrayList = new ArrayList();
    arrayList.add(12);
    ListIterator listIterator = arrayList.listIterator();

    while(listIterator.hasNext()){
    Integer input =listIterator.next();
    System.out.println(input);//Prints 12
    listIterator.add(input+1);
    }

    1. Praveen E says:

      Hi Praveen, here is another Praveen answering your question

      From what I observed during debugging, whenever add method is called, cursor of the iterator is being incremented one time.

      If the list is 1,2,3,4,5,6

      Initially the cursor will be at list(0). When you do listIterator.next() , cursor will be moved to list(1) position. And as you are inserting some value into the list at this point you will expect that the list will keep on going to infinite loop. But what happens is, when you perform add() operation, the cursor will also be incremented by one. So, that means instead of pointing to the newly added element, the cursor will be pointed to list(2) whose value is 2.

      But the same will cause infinite loop in listIterator.previous() usage as ListIterator.previous() would decrement the cursor by one value and ListIterator().add() method would increment the cursor by one value. So, the cursor will always point to newly added element.

  3. Praveen says:

    Eventhough, we add one element via listIterator to arrayList during iteration, it will not go infinite loop. Can anyone explain logic?
    ArrayList arrayList = new ArrayList();
    arrayList.add(12);
    ListIterator listIterator = arrayList.listIterator();

    while(listIterator.hasNext()){
    Integer input =listIterator.next();
    System.out.println(input);//Prints 12
    listIterator.add(input+1);
    }

    1. ganesh says:

      ArrayList arrayList = new ArrayList();
      arrayList.add(12);
      ListIterator listIterator = arrayList.listIterator();

      while(listIterator.hasNext()){
      Integer input =(Integer)listIterator.next();
      System.out.println(input);//Prints 12
      listIterator.add(13);
      listIterator.previous();
      //listIterator.next();
      System.out.println(listIterator.next());
      }
      ouput: 12 13

      praveen check this u will get knowledge of it.
      https://stackoverflow.com/questions/18995038/what-does-list-iterators-add-method-do-to-the-iterator

  4. Kiran says:

    Bi-Directional Iterators
    They are Cursors which supports Both Forward Direction and Backward Direction iterations. For instance, ListIterator are *****Bi******-Directional Iterators.

  5. Biswajit Sahu says:

    Very nicely explained. Thank you.

  6. Naga says:

    Thanks a lot for good explanation.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages