Обратная итерация через ArrayList дает исключение IndexOutOfBoundsException - PullRequest
30 голосов
/ 24 февраля 2009

Когда я переворачиваю итерацию ArrayList, я получаю исключение IndexOutOfBoundsException. Я попытался сделать итерацию вперед, и нет проблем. Я ожидаю и знаю, что в списке пять элементов. Код ниже:

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

Прямая итерация - которая работает нормально, но не полезна для меня:

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

Ошибка:

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)

Также, если кто-нибудь знает лучшую идиому для обратной итерации, я был бы счастлив попробовать это.

Ответы [ 9 ]

87 голосов
/ 30 июня 2009

Избегать индексов вообще? Как насчет:

for (ListIterator iterator = list.listIterator(list.size()); iterator.hasPrevious();) {
  final Object listElement = iterator.previous();
}
64 голосов
/ 24 февраля 2009

Начните итерацию с list.size() - 1, поскольку элементы массива (или ArrayList) пронумерованы от 0 до 1, что меньше размера списка. Это довольно стандартная идиома:

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

Обратите внимание, что ваша прямая итерация работает, потому что она останавливается до того, как достигнет list.size().

27 голосов
/ 04 июля 2011

Я знаю, что это старый вопрос, но в Java есть метод Collections.reverse( List<T> ). Почему бы вам просто не повернуть вспять и не выполнить итерацию вперед?

12 голосов
/ 29 августа 2012

Самый элегантный способ - обратить массив и затем использовать прямой (или даже неявный) итератор:

Collections.reverse(arrayList);
for (Object item : arrayList) {
    ...
}
11 голосов
/ 24 февраля 2009

list.size () находится за последним допустимым индексом.

for(int j = list.size() - 1; j >= 0; j--) {
  System.out.println(list.get(j));
}
4 голосов
/ 24 февраля 2009

Java-массивы индексируются нулем. Вам нужно будет установить j = list.size () - 1 и продолжать до j = 0.

3 голосов
/ 27 мая 2014

Если списки довольно малы, так что производительность не является реальной проблемой, можно использовать reverse -метод Lists -класса в Google Guava. Дает довольно for-each -код, и оригинальный список остается прежним. Кроме того, обратный список поддерживается исходным списком, поэтому любое изменение исходного списка будет отражено в обратном.

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

Дает следующий результат:

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

Это означает, что обратная итерация myList может быть записана как:

for (final String someString : Lists.reverse(myList) {
    //do something
}
0 голосов
/ 09 июня 2018

Вы можете сделать это, если вам удобен цикл foreach.

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());
}
0 голосов
/ 29 мая 2016

Вы можете повернуть на одну строку, которая

Collections.reverse (список);

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

выход

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