Question

When I reverse iterate over an ArrayList I am getting a IndexOutOfBoundsException. I tried doing forward iteration and there is no problem. I expect and know that there are five elements in the list. The code is below:

Collection rtns = absRtnMap.values();
List list = new ArrayList(rtns);
Collections.sort(list);

for(int j=list.size();j>0;j=j-1){
  System.out.println(list.get(j));
}

Forward iteration - which is working fine, but not useful for me:

for(int j=0;j<list.size();j++){
    System.out.println(list.isEmpty());
    System.out.println(list.get(j));
} // this worked fine

The error:

Exception in thread "Timer-0" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
    at java.util.ArrayList.RangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at model.Return.getReturnMap(Return.java:61)
    at controller.Poller$1.run(Poller.java:29)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

Also if anyone knows of a better idiom for reverse iteration I would be happy to try that out.

Was it helpful?

Solution

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().

OTHER TIPS

Avoid indexes altogether? How about:

for (ListIterator iterator = list.listIterator(list.size()); iterator.hasPrevious();) {
  final Object listElement = iterator.previous();
}

I know this is an old question, but Java contains a Collections.reverse( List<T> ) method. Why wouldn't you just reverse it and do forward iteration?

The most elegant way is to reverse the array and then use a direct (or even implicit) iterator :

Collections.reverse(arrayList);
for (Object item : arrayList) {
    ...
}

The list.size() is past the last allowable index.

for(int j = list.size() - 1; j >= 0; j--) {
  System.out.println(list.get(j));
}

Java arrays are zero-indexed. You will have to set j = list.size() - 1 and continue until j = 0.

If the lists are fairly small so that performance is not a real issue, one can use the reverse-metod of the Lists-class in Google Guava. Yields pretty for-each-code, and the original list stays the same. Also, the reversed list is backed by the original list, so any change to the original list will be reflected in the reversed one.

import com.google.common.collect.Lists;

[...]

final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);

System.out.println(myList);
System.out.println(myReverseList);

myList.add("four");

System.out.println(myList);
System.out.println(myReverseList);

Yields the following result:

[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]

Which means that reverse iteration of myList can be written as:

for (final String someString : Lists.reverse(myList) {
    //do something
}

You can reverse by one line that is

Collections.reverse(list);

ArrayList arrayList = new ArrayList();

arrayList.add("A");
arrayList.add("B");

System.out.println("Before Reverse Order : " + arrayList);

Collections.reverse(arrayList);

System.out.println("After Reverse : " + arrayList);

Output

Before Reverse Order : [A, B]
After Reverse : [B, A]

You can do this if you are comfortable with foreach loop.

List<String> list = new ArrayList<String>();
list.add("ABC");
list.add("DEF");
list.add("GHI");

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

while(listIterator.hasPrevious()){
  System.out.println(listIterator.previous());
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top