javareverseforeach

Can one do a for each loop in java in reverse order?


I need to run through a List in reverse order using Java.

So where this does it forwards:

for(String string: stringList){
//...do something
}

Is there some way to iterate the stringList in reverse order using the for each syntax?

For clarity: I know how to iterate a list in reverse order but would like to know (for curiosity's sake ) how to do it in the for each style.


Solution

  • One approach would be to reverse the whole list, but this would have O(n) performance with respect to its size. Note that the commonly-used Collections.reverse method actually reverses the original list in place, which may be an undesirable side-effect.

    As a more efficient solution, you could write a decorator that presents a reversed view of a List as an Iterable. The iterator returned by your decorator would use the ListIterator of the decorated list to walk over the elements in reverse order.

    For example:

    public class Reversed<T> implements Iterable<T> {
        private final List<T> original;
    
        public Reversed(List<T> original) {
            this.original = original;
        }
    
        public Iterator<T> iterator() {
            final ListIterator<T> i = original.listIterator(original.size());
            
            return new Iterator<T>() {
                public boolean hasNext() { return i.hasPrevious(); }
                public T next() { return i.previous(); }
                public void remove() { i.remove(); }
            };
        }
    
        public static <T> Reversed<T> reversed(List<T> original) {
            return new Reversed<T>(original);
        }
    }
    

    And you would use it like:

    import static Reversed.reversed;
    
    ...
    
    List<String> someStrings = getSomeStrings();
    for (String s : reversed(someStrings)) {
        doSomethingWith(s);
    }
    

    Update for Java 21

    As per this answer, Java 21 includes an efficient List.reversed() method which does exactly what is requested.