Java: Iterate over a list in the reverse order example

06 January 2013
By Gonçalo Marques
In this tutorial you will learn how to iterate over a Java list in the reverse order.

Introduction

A simple approach of iterating a list in the reverse order may consist in simply revert a list using Collections.reverse() and then performing a natural iteration over the elements. Sometimes this approach may not be acceptable. Supposing that our list is holding a considerable number of items that makes the reverse operation itself to impact the overall application performance. It doesn't make sense to spend CPU cycles reversing the list if what we want to do is just to iterate its elements in the reverse order.

This tutorial considers the following software and environment:

  1. Ubuntu 12.04
  2. JDK 1.7.0.09

The ListIterator interface

The ListIterator interface is a special kind of iterator designed to iterate over lists. It provides functionality that is not available in regular iterators such as iterating a list in either direction. With this in mind we can iterate a list in the reverse order by just using the ListIterator interface:

ListIterator interface

List<String> list = new ArrayList<String>();
list.add("First");
list.add("Second");
list.add("Third");

ListIterator<String> listIterator = list.listIterator(list.size());

while(listIterator.hasPrevious()){
  System.out.println(listIterator.previous());
}

List.listIterator() method returns an iterator that is ready to transverse the list in whatever direction we want. The method may take a parameter that defines the starting index of the iteration. We defined this position to be n because lists are zero-based indexed so the first call to previous() will return the last element in the list. As we can see it's easy to transverse a list in the reverse order, but what about making this reusable?

Making it reusable

Every class that implements the Iterable interface it's declaring itself as iterable so it must provide an Iterator. This way the callers are able to iterate over elements in some data structure provided by the class. With this in mind we can write something like the following:

ReversedIterator class
package com.byteslounge.collections;

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ReversedIterator<T> implements Iterable<T> {

  private List<T> list;
  
  public ReversedIterator(List<T> list){
    this.list = list;
  }
  
  //Iterator provided to clients of this class
  @Override
  public Iterator<T> iterator() {
    
    // Every time an iterator is requested we
    // define a new ListIterator that will be used to
    // iterate the list in the reverse order
    final ListIterator<T> iterator = list.listIterator(list.size());
    
    // The iterator returned to the caller will
    // work based on the ListIterator
    return new Iterator<T>(){

      // hasNext() and next() methods call in fact
      // the reverse operations in ListIterator
      
      @Override
      public boolean hasNext(){
        return iterator.hasPrevious();
      }

      @Override
      public T next(){
        return iterator.previous();
      }

      @Override
      public void remove() {
        iterator.remove();
      }

    };

  }
}

Our ReversedIterator class receives the list we want to do reverse iteration in the constructor. The iterator() method builds a new ListIterator when it's called by a client and returns an Iterator that will work based on this ListIterator. When the Iterator methods are called we use the created ListIterator to perform the reverse operations. We made this class generic so it can be used with any data type.

Testing

Let's test it:

Test class

package com.byteslounge.collections;

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

public class Main {

  public static void main(String [] args){
    
    List<String> list = new ArrayList<String>();
    list.add("First");
    list.add("Second");
    list.add("Third");
    
    ReversedIterator<String> reversedList = 
         new ReversedIterator<String>(list);
    
    // for-each syntax
    for(String s : reversedList){
      System.out.println(s);
    }
    
    System.out.println("");
    
    // iterator syntax
    Iterator<String> iterator = reversedList.iterator();
    while(iterator.hasNext()){
      System.out.println(iterator.next());
    }
    
  }
}

The output generated by this test class will be the following:

Third
Second
First

Third
Second
First

The example source code is available at the end of this page.

Download source code from this article

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: