Every collection provides an iterator, which allows the Java programmer to access elements of any collection using the methods defined in the Iterator interface.
Iterators in Java
The iterators in Java can be thought of as a general-purpose and standardized way of accessing elements of a collection in the same way one uses a variable, say i, to iterate through an array using a for loop. Java Iterator interface is closely associated with the Java Collections Framework. It comes as a part of the Java.util package.
Some utilities generally associated with iterators are the retrieval, access, insertion, or deletion of elements related to any collection. Iterators in Java are not limited to the Iterator interface. However, interfaces in Java are critical.
There are three types of iterators available in Java.
- Iterator
- ListIterator
- Enumeration
We shall discuss each type of Iterator in Java one by one.
Iterator
As discussed earlier, the Iterator interface provides methods for every collection which can be used to access elements of that collection. An element can be inserted, deleted, accessed, or retrieved using the said methods. The Iterator interface is a part of the Java.util package as follows:
public interface java.util.Iterator<E> { public abstract boolean hasNext(); public abstract E next(); public void remove(); public void forEachRemaining(java.util.function.Consumer<? super E>); }
The following methods are part of the Iterator interface:
boolean hasNext()
Returns true if more elements are present in the collection left to be traversed. Otherwise, it returns false.
Syntax : public abstract boolean hasNext( )
Object next()
Returns the next element to the element the Iterator is presently pointing to. Throws NoSuchElementException when no such element exists that can be retrieved this way.
Syntax : public abstract Object next()
void remove()
Removes the last element that gets retrieved by the next( ) method. Throws IllegalStateException if remove( ) is called before next( ). Throws UnsupportedOperationException when remove() is unsupported.
Syntax : public void remove()
void forEachRemaining(Consumer <? super Object> action)
Performs the specified action on each remaining element in the collection.
Syntax : public void forEachRemaining(Consumer <? super Object > action)
See the following code example.
import java.util.LinkedList; import java.util.Iterator; class Example1 { public static void main(String [] args) { //creating a LinkedList and adding elements it in LinkedList<String> list=new LinkedList<>(); list.add("Agra"); list.add("Agartala"); list.add("Mumbai"); list.add("Amethi"); list.add("Jhansi"); //creating an Iterator to traverse LinkedList Iterator cursor=list.iterator(); //print all the city names where names start A and remove the others from the LinkedList System.out.println("Cities starting with alphabet A in the list are: "); while(cursor.hasNext()==true) String o=(String)cursor.next(); System.out.println(o); else cursor.remove(); } } }
See the following output.
ListIterator
While iterators of the Iterator interface allow the Java programmer to travel only in one direction, one might feel the need for bi-directional traversal in specific data structures.
For collections such as lists ( an ArrayList, for example), Java provides a particular iterator interface called the ListIterator.
The ListIterator interface is a part of the Java.util package and implements the Iterator interface itself. The general definition of the ListIterator interface in Java is as follows:
public interface java.util.ListIterator<E> extends java.util.Iterator<E> { public abstract boolean hasNext(); public abstract E next(); public abstract boolean hasPrevious(); public abstract E previous(); public abstract int nextIndex(); public abstract int previousIndex(); public abstract void remove(); public abstract void set(E); public abstract void add(E); }
See the following diagram.
To use a ListIterator object, the methods next() and previous() refer to the two elements between which these iterator points. This is because objects of ListIterator only point between elements and not directly to any “current” element as done by other iterators.
To create an object of ListIterator, the method listIterator() is called. This is demonstrated along with the use of this Iterator in the following example:
import java.util.ArrayList; import java.util.ListIterator; class Example2 { public static void main(String []args) { //creating an arraylist and adding values in it ArrayList<Integer> num=new ArrayList<>(); num.add(1); num.add(2); num.add(3); num.add(4); num.add(5); //creating a ListIterator ListIterator cursor=num.listIterator(); //traversing the list and printing its value System.out.println("The original list is:"); while(cursor.hasNext()==true) { int index=cursor.nextIndex(); int n=(Integer)cursor.next(); System.out.println("value at "+index+" is : "+n); } //modifying the list by replacing values with their squares while traversing in backward direction while(cursor.hasPrevious()==true) { int n=(Integer)cursor.previous(); int sq=n*n; cursor.set(sq); } //traversing the list and printing its value System.out.println("The modified list is:"); while(cursor.hasNext()==true) { int index=cursor.nextIndex(); int n=(Integer)cursor.next(); System.out.println("value at "+index+" is : "+n); } } }
See the following output.
The following methods are part of the ListIterator interface:
boolean hasNext()
Returns true if more elements are present in the collection left to be traversed in the forward direction. Otherwise, it returns false.
Syntax : public abstract boolean hasNext( )
boolean hasPrevious()
Returns true if more elements are present in the collection left to be traversed in the backward direction. Otherwise, it returns false.
Syntax : public abstract boolean hasPrevious( )
Object next()
Returns the next element to the element the Iterator is presently pointing to. Throws NoSuchElementException when no such element exists that can be retrieved this way.
Syntax : public abstract Object next()
Object previous()
Returns the previous element to the element the Iterator is presently pointing to. Throws NoSuchElementException when no such element exists that can be retrieved this way.
Syntax : public abstract Object previous()
int nextIndex()
Returns the index of the next element. Returns the size of the list if no more elements are left as next.
Syntax : public abstract int nextIndex()
int previousIndex()
Returns the index of the previous element. Returns -1, if no more elements are there before the Iterator.
Syntax : public abstract int previousIndex()
void remove( )
Removes the last element retrieved by the next( ) or previous() methods. Throws IllegalStateException if remove( ) is called before either of these methods. Throws UnsupportedOperationException when remove() is unsupported.
Syntax : public abstract void remove()
void add(Object ob)
It adds objects just before the element is returned by the next() method or just after the element returned by the previous(). Throws UnsupportedOperationException, ClassCastException if the object in question cannot be added due to the nature of its class. It throws IllegalArgumentException for illegal arguments.
Syntax : public abstract void add(Object ob)
void set(Object ob)
Replaces object passed in an argument with the last element retrieved by next() or previous() methods. Throws UnsupportedOperationException, IllegalStateException, ClassCastException, and IllegalArgumentException in usual conditions of these exceptions.
Syntax: public abstract void set(Object ob)
Enumeration
Introduced as early as in JDK 1.0 itself, the Enumeration interface differs from the other iterators because it doesn’t provide direct methods to add or remove elements. This makes the other iterators more advanced than the said Enumeration, and needless to say hence, the Java API docs also suggest the use of Iterator over Enumeration.
The Enumeration iterator in Java is mainly designed to traverse through the Vector class and Hashtable class. To create an enumeration for a Vector class, the elements() method (present in the Vector class itself) is called, and similarly, for Hashtable, keys() method is called.
The following is the definition of the Enumeration interface in the Java.util package.
public interface java.util.Enumeration<E> { public abstract boolean hasMoreElements(); public abstract E nextElement(); }
As Enumeration is fail-safe, it doesn’t throw any exceptions such as ConcurrentModificationException, which is the case with Iterator, for example, which happens when a collection is modified during traversal. This, no doubt, in the case of Enumeration, compromises the safety and security clause, which is an essential part of any Java concept.
The following methods are part of the Enumeration interface:
boolean hasMoreElements(): This method can be used to check whether there are more elements to traverse or not. Returns value in boolean.
Syntax : public abstract boolean hasMoreElements()
Object nextElement(): This method is used to return the immediate next element from the element presented pointed to by the Enumeration. Throws NoSuchElementException.
Syntax : public abstract Object nextElement()
The following program demonstrates the working of Enumeration.
See the following code example.
import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; class Example3 { public static void main(String [] args) { //creating a vector and inserting elements in it Vector colour= new Vector(); colour.addElement("blue"); colour.addElement("red"); colour.addElement("green"); //creating enumeration for traversing vector Enumeration cursor=colour.elements(); //traversing vector System.out.println("Vector is: "); while(cursor.hasMoreElements()==true) { System.out.println(cursor.nextElement()); } //creating Hashtable (a key value pair) Hashtable<Integer, String> table = new Hashtable<>(); table.put(1,"dog"); table.put(2,"cat"); table.put(3,"lion"); //creating enumeration for traversing the hashtable Enumeration traverse = table.keys(); //traversing the hashtable System.out.println("Hashtable is: "); while(traverse.hasMoreElements()) { Integer key = (Integer)traverse.nextElement(); System.out.println(key+" "+table.get(key)); //get method is used to fetch the value of corresponding key } } }
See the following output.
That’s it for this tutorial.