Iterating Through a List in Reverse Order in Java

Iterating through a list in reverse order in java

Try this:

// Substitute appropriate type.
ArrayList<...> a = new ArrayList<...>();

// Add elements to list.

// Generate an iterator. Start just after the last element.
ListIterator li = a.listIterator(a.size());

// Iterate in reverse.
while(li.hasPrevious()) {
System.out.println(li.previous());
}

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

The Collections.reverse method actually returns a new list with the elements of the original list copied into it in reverse order, so this has O(n) performance with regards to the size of the original list.

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);
}

making a list that maintains a reverse order by its own

Your ReverseIterator is a subclass of ReverseList. This means, it is a list on its own. Then, you are mixing up the state of these two lists. In the ReverseIterator(ReverseList<E> r), you use r’s size to initialize pos, in next() you use super.get(pos--), accessing the other list’s content. This other list is always empty.

An iterator should never be a collection. When you implement an iterator as an inner class, you can access the outer collection’s state implicitly.

Besides that, your list clearly violates the contract of the List interface and will cause a lot of other problems in the future, as its iterator() is inconsistent with other List features, like all index based operations or listIterator().

You should not change the fundamentals of a class, just for the sake of a single operation (i.e. iterate backwards). Rather, implement this single operation as a distinct operation.

For example:

public class ReversibleList<T> extends ArrayList<T> {
private class ReverseIterator implements Iterator<T> {
private int pos = size() - 1;

@Override
public boolean hasNext() {
return pos >= 0;
}

@Override
public T next() {
return get(pos--);
}
}

public Iterable<T> reverse() {
return () -> new ReverseIterator();
}

public static void main(String[] args) {
ReversibleList<Integer> r = new ReversibleList<>();
r.add(1);
r.add(2);
r.add(3);
r.add(4);

for(Integer i: r.reverse()) {
System.out.println(i);
}
}
}

The reverse() view has no storage of its own but always reflects the current contents of the list, in reverse order. The original List keeps fulfilling its contract.

Note that it is possible to create reversed view to a list supporting other operations of the List interface beyond iterator():

public class ReversibleList<T> extends ArrayList<T> {
private class ReversedList extends AbstractList<T> implements RandomAccess {
@Override
public T get(int index) {
return ReversibleList.this.get(size() - index - 1);
}

@Override
public int size() {
return ReversibleList.this.size();
}
}

public List<T> reverse() {
return new ReversedList();
}

public static void main(String[] args) {
ReversibleList<Integer> r = new ReversibleList<>();
r.add(1);
r.add(2);
r.add(3);
r.add(4);

r.reverse().subList(1, 4).stream().forEach(System.out::println);
}
}

Reverse iteration through ArrayList gives IndexOutOfBoundsException

Start the iteration at list.size() - 1 because array (or ArrayList) elements are numbered from 0 up through 1 less than the size of the list. This is a fairly standard idiom:

for (int j = list.size() - 1; j >= 0; j--) {
// whatever
}

Note that your forward iteration works because it stops before reaching list.size().

Iterate List in Reverse from a specific Index

You can use Collections.rotate in combination with Collections.reverse with out the need of a new list or a for loop:

public static void main(String[] args) {
//original: 4 5 8 7
//expected: 8 5 4 7

List<Integer> mylist = new ArrayList<>(Arrays.asList(4,5,8,7));
System.out.println("Original List : " + mylist);

int distance = mylist.indexOf(8) + 1;
Collections.reverse(mylist);
Collections.rotate(mylist, distance);

System.out.println("Rotated List: " + mylist);
}

How to iterate a LinkedList elements in reverse order?

I think you want a descendingIterator.

Iterator lit = obj.descendingIterator();
System.out.println("Backward Iterations");
while(lit.hasNext()){
System.out.println(lit.next());
}

Java reverse foreach

It's fundamentally impossible because the foreach loop is based on the Iterable and Iterator interfaces, and those don't have a notion of reverse iteration.

Looping through the elements in an array backwards

Arrays in Java are indexed from 0 to length - 1, not 1 to length, therefore you should be assign your variable accordingly and use the correct comparison operator.

Your loop should look like this:

for (int counter = myArray.length - 1; counter >= 0; counter--) {


Related Topics



Leave a reply



Submit