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
Selenium Webdriver: Wait for Complex Page with JavaScript to Load
How to Sort Arraylist<Long> in Decreasing Order
How to View Tomcat Log Files in Eclipse
Comparing Time Is Incorrect When Picking 12:00
How to Define a Method Which Takes a Lambda as a Parameter in Java 8
How to Calculate the Difference Between Two Arraylists
How to Check If a Url Exists or Returns 404 with Java
Calling Super Super Class Method
Generating a Random Number Between 1 and 10 Java
How to Return JSON Data from Spring Controller Using @Responsebody
In Java, What Are the Boolean "Order of Operations"
Spring Configure @Responsebody JSON Format
What's the Default Value of Char
How to Set Java_Home in MAC Permanently
Jpa: What Is the Proper Pattern for Iterating Over Large Result Sets
Grab a Segment of an Array in Java Without Creating a New Array on Heap