The most natural method of iterating through a list in Java is to start from the first element of the list and then move forward until the last one is reached. While this is the most common, it is sometimes necessary to do it otherwise – start from the last element and move in reverse direction. In this post I would like to show 4 different ways to do it easily.
This short class creates a simple list and calls 4 methods to print it in reverse order:
package com.example.iteratelistreverse; import com.google.common.collect.Lists; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.apache.commons.collections.iterators.ReverseListIterator; public class Main { public static void main(String[] args) throws IOException { List<String> list = new ArrayList<>(); list.add("First"); list.add("Second"); list.add("Third"); list.add("Fourth"); list.add("Fifth"); iterateIndexedAccess(list); iterateListIterator(list); iterateReverseListIterator(list); iterateListsReverse(list); } private static void iterateIndexedAccess(List<String> list) { System.out.print("\nFor loop with random access:\n"); for (int i = list.size() - 1; i >= 0; i--) { System.out.println(list.get(i)); } } private static void iterateListIterator(List<String> list) { System.out.print("\nList iterator:\n"); ListIterator<String> it = list.listIterator(list.size()); while (it.hasPrevious()) { System.out.println(it.previous()); } } private static void iterateReverseListIterator(List<String> list) { System.out.print("\nApache ReverseListIterator:\n"); Iterator<String> it = new ReverseListIterator(list); while (it.hasNext()) { System.out.println(it.next()); } } private static void iterateListsReverse(List<String> list) { System.out.print("\nGuava List.reverse:\n"); for (String v : Lists.reverse(list)) { System.out.println(v); } } }
Method iterateIndexedAccess() shows the most common solution. In this method we are using the indexed access to the elements of the list which is very easy and obvious. It has also very good performance assuming that the instance of the list supports fast random access. It is the case for very popular ArrayList class.
However, other classes may not support fast random access. One of the examples is LinkedList class. For every List.get() method call this class has to iterate from the beginning (or alternatively from the end) of the list to find the element at given index which makes it very slow for large lists.
Method iterateListIterator() overcomes this problem by using a list iterator which can move forward and backward using ListIterator.next() and ListIterator.previous() calls respectively. In our example we are starting from the position after the last element and are moving to the previous element on every loop iteration.
Method iterateReverseListIterator() is quite specific because it creates an iterator which pretends that it is normal iterator (forward iterator). In fact it starts from the last element of the list and moves to the previous one on every call to Iterator.next() method. This solution uses ReverseListIterator class from Apache Commons library.
The last way uses method Lists.reverse() from Guava library to create a reversed view of the given list. Once we have the view, which is in fact instance of Iterable interface, we can go over it using enhanced loop.
As usual you can find the source code of this example at GitHub.
In case of LinkedList one can use descendingIterator() method for iterating in the reverse direction.