Iterator vs. ListIterator: Which interface should you choose?

When the need exists to manipulate an ordered collection, the Java Iterator runs out of steam. Learn how Java's ListIterator improves upon the more generic Iterator interface.

The Java Iterator is an all-purpose interface that simplifies looping through a collection of objects. Java's ListIterator provides all the functionality of the Iterator interface, with four additional methods that work with collections ordered by a numeric index.

The fundamental difference between the Java Iterator and ListIterator is the ListIterator's ability to manipulate an ordered list.

Let's compare the Java Iterator vs. ListIterator interfaces and find which one makes the most sense in different scenarios.

Iterators, ListIterators and Collections

In computer programming, a collection is defined as a group of objects. In Java, a collection is any class or interface that implements the Collection interface. Commonly used implementing classes include:

  • List
  • ArrayList
  • Set
  • HashSet
  • Queue
  • Vector

The Collection interface defines methods that help developers work with a group of objects. Any Java developer who has interacted with a collection class would be familiar with methods such as add(), clear(), remove() and iterator(), all of which are defined in the Collection interface.

Since methods defined in the Collection interface must follow rules that would sensibly apply to all classes that implement it, the JVM makes no assumptions about the concrete classes that will contract with it.  As such, methods defined in the Iterator returned by the Collection interface's iterate() method must be general enough to work with every concrete class that uses it.

Iterator vs ListIterator Class Diagram
The Java Iterator is accessible to all Collection classes, but the ListIterator is confined only to classes that implement the List interface.

Java Collections Framework

However, classes in the Java Collections Framework provide a wide range of functionality, especially when it comes to how contained elements are managed, sorted, compared and ordered. For example:

  • Some collection classes -- such as lists -- associate every object added with a numeric index that implies order.
  • Some collection classes -- such as sets -- make sure all contained objects are unique, but make no guarantees about how their contents are ordered.
  • Some classes -- like the HashMap or Hashtable -- associate contained elements with keys rather than an ordinal index, which means index-based ordering is not possible.

When it comes to the functionality provided by the Iterator vs. ListIterator, some collection classes numerically order the objects they contain, while others do not order their elements at all.

ListIterators and ordered collections

The primary reason developers need to work with an ordered collection is to choose a List over a Set or a Queue. When a developer works with a List, there will inevitably be situations where the collection needs to be manipulated based on the ordering of the objects it contains.

To provide additional functionality a developer might need when looping through an ordered collection, the Java API provides a special type of Iterator named the ListIterator. This interface includes all the public methods defined in the inherited Iterator interface, while it additionally defines four extra methods that only make sense with an ordered collection.

Iterator vs. ListIterator comparison chart

Additional ListIterator Methods

As of the Java 17 release, there are four methods in the ListIterator interface not found in the more abstract Iterator:

  • hasPrevious() - returns the previous object in an ordered list
  • nextIndex() - returns the numeric index of the element that is next in the list
  • previousIndex() - returns the numeric index of the previous element in the ordered list
  • add() - inserts an object into an ordered list at a specific location

Iterator vs. ListIterator interfaces

A fundamental Java design pattern is to program to an interface.

An implicit part of this design pattern is that it asserts you should use the most generic interface possible to make your code accessible to as many sub-types as possible. The first instinct of every developer should be to choose the Java Iterator over the more specialized ListIterator. However, there are cases where Java's ListIterator bests the Iterator.

Iterator vs. ListIterator: Which one should I use?

Developers should choose the ListIterator over the Iterator when the underlying collection class is numerically ordered and at least one of the following three requirements hold true:

  1. There is a need to insert a class into a specific spot in the ordered collection.
  2. There is a requirement to navigate backwards through an ordered collection.
  3. There is a need to obtain the numeric index of the previous or next element in an ordered collection.

The Java Collections Framework provides a wealth of classes, interfaces, enums and records to help simplify list processing and manipulating groups of related objects. When the correct components are used to solve a complex problem, the applications that elute will be easier to manage, easier to maintain and perform optimally when they are continuously deployed, which is always the ultimate goal when developing software applications.

About the author

Dmytro Vezhnin is CEO and co-founder at CodeGym.cc, an interactive educational platform where people can learn Java programming language from scratch to Java Junior level.

Dig Deeper on Core Java APIs and programming techniques

App Architecture
Software Quality
Cloud Computing