Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

Iterating over the elements of a list is one of the most common tasks in a program.

In this tutorial, we’ll review the different ways to do this in Java. We’ll focus on iterating through the list in order, though going in reverse is simple, too.

Further reading:

Iterate Over a Set in Java

Learn look at how to iterate over the elements of a <em>Set</em> in Java.

Iterate Over a Map in Java

Learn different ways of iterating through the entries of a Map in Java.

How to Iterate Over a Stream With Indices

Learn several ways of iterating over Java 8 Streams using indices

2. for Loop

First, let’s review some for loop options.

We’ll begin by defining a list of countries for our examples:

List<String> countries = Arrays.asList("Germany", "Panama", "Australia");

2.1. Basic for Loop

The most common flow control statement for iteration is the basic for loop.

The for loop defines three types of statements separated with semicolons. The first statement is the initialization statement. The second one defines the termination condition. The last statement is the update clause.

Here we’re simply using an integer variable as an index:

for (int i = 0; i < countries.size(); i++) {
    System.out.println(countries.get(i));
}

In the initialization, we must declare an integer variable to specify the starting point. This variable typically acts as the list index.

The termination condition is an expression that returns a boolean after evaluation. Once this expression evaluates to false, the loop finishes.

The update clause is used to modify the current state of the index variable, increasing it or decreasing it until the point of termination.

2.2. Enhanced for Loop

The enhanced for loop is a simple structure that allows us to visit every element of a list. It’s similar to the basic for loop, but more readable and compact. Consequently, it’s one of the most commonly used forms to traverse a list.

Notice that the enhanced for loop is simpler than the basic for loop:

for (String country : countries) {
    System.out.println(country); 
}

3. Iterators

An Iterator is a design pattern that offers us a standard interface to traverse a data structure without having to worry about the internal representation.

This way of traversing data structures offers many advantages, among which we can emphasize that our code doesn’t depend on the implementation.

Therefore, the structure can be a binary tree or a doubly linked list, since the Iterator abstracts us from the way of performing the traversal. In this way, we can easily replace data structures in our code without unpleasant problems.

3.1. Iterator

In Java, the Iterator pattern is reflected in the java.util.Iterator class. It’s widely used in Java Collections. There are two key methods in an Iterator, the hasNext() and next() methods.

Here we’ll demonstrate the use of both:

Iterator<String> countriesIterator = countries.iterator();

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

The hasNext() method checks if there are any elements remaining in the list.

The next() method returns the next element in the iteration.

3.2. ListIterator

A ListIterator allows us to traverse a list of elements in either forward or backward order.

Scrolling a list with ListIterator forward follows a mechanism similar to that used by the Iterator. In this way, we can move the iterator forward with the next() method, and we can find the end of the list using the hasNext() method.

As we can see, the ListIterator looks very similar to the Iterator that we used previously:

ListIterator<String> listIterator = countries.listIterator();

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

4. forEach()

4.1. Iterable.forEach()

Since Java 8, we can use the forEach() method to iterate over the elements of a list.  This method is defined in the Iterable interface, and can accept Lambda expressions as a parameter.

The syntax is pretty simple:

countries.forEach(System.out::println);

Before the forEach function, all iterators in Java were active, meaning they involved a for or while loop that traversed the data collection until a certain condition was met.

With the introduction of forEach as a function in the Iterable interface, all classes that implement Iterable have the forEach function added.

4.2. Stream.forEach()

We can also convert a collection of values to a Stream, and have access to operations such as forEach()map(), and filter().

Here we’ll demonstrate a typical use for streams:

countries.stream().forEach((c) -> System.out.println(c));

5. Conclusion

In this article, we demonstrated the different ways to iterate over the elements of a list using the Java API. These options included the for loop, enhanced for loop, Iterator, ListIterator, and the forEach() method (included in Java 8).

Then we learned how to use the forEach() method with Streams.

Finally, all the code used in this article is available in our Github repo.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.