Java - Collections Traversing - Iterator

Introduction

The Collections Framework provides the following ways to traverse a collection:

  • Using an Iterator
  • Using a for-each loop
  • Using the forEach() method

You can traverse some collections using a regular for-loop statement.

You can also traverse collections by converting them into streams and performing an aggregate operation on those streams.

Iterator

A collection provides an iterator to iterate over all its elements.

An iterator in Java is an instance of the Iterator<E> interface.

You can get an iterator for a collection using the iterator() method the Collection interface.

The following code creates a list of strings and gets an iterator for the list:

// Create a list of strings
List<String> names = new ArrayList<>();
// Get an iteratir for the list
Iterator<String> nameIterator = names.iterator();

The Iterator<E> interface contains the following methods:

boolean hasNext()
E next()
default void remove()
default void forEachRemaining(Consumer<? super E> action)

hasNext() method returns true if there are more elements in the collection to iterate. Otherwise, it returns false.

next() method returns the next element from the collection.

If you call the next() method and the iterator has no more elements to return, it throws a NoSuchElementException.

The following code prints all elements of a list using an iterator:

List<String> names = // get a list;

// Get an iterator for the list
Iterator<String> nameIterator = names.iterator();

// Iterate over all elements in the list
while(nameIterator.hasNext()) {
        // Get the next element from the list
        String name = nameIterator.next();

        // Print the name
        System.out.println(name);
}

remove() method removes the element of the collection that was returned last time by calling the next() method of the iterator.

remove() method can be called only once per call to the next() method.

The support for the remove() method is optional, which may throw an UnsupportedOperationException if the iterator does not support the remove operation.

The following code iterates over all elements of a list using an iterator and removes the element using the remove() method of the iterator if the element is only two characters long:

List<String> names = get a list;

// Get an iterator for the list
Iterator<String> nameIterator = names.iterator();

// Iterate over all elements in the list
while(nameIterator.hasNext()) {
        String name = nameIterator.next();
        // Remove the name if it is two characters
        if (name.length() == 2) {
                nameIterator.remove();
        }
}

forEachRemaining() method takes an action on each element of the collection that has not been accessed by the iterator yet.

The action is specified as a Consumer. You can use the following code to print all elements of a list:

The code uses method reference System.out::println as a Consumer for the forEachRemaining() method.

List<String> names = get a list;

// Get an iterator for the list
Iterator<String> nameIterator = names.iterator();

// Print the names in the list
nameIterator.forEachRemaining(System.out::println);

The following code uses an iterator and the forEachRemaining() of the iterator to print all elements of a list on the standard output.

Demo

import java.util.ArrayList;
import java.util.List;

public class Main {
  public static void main(String[] args) {
    // Create a list of strings
    List<String> names = new ArrayList<>();

    // Add some names to the list
    names.add("Java");
    names.add("Javascript");
    names.add("Joe");

    // Print all elements of the names list
    names.iterator().forEachRemaining(System.out::println);
  }/*from w  w w .  ja  v a  2 s .c  om*/
}

Result

Iterator is a one-time object and you cannot reset an iterator.

To iterate over the elements of the same collection again, obtain a new Iterator calling the iterator() method of the collection.