Java 通过 ArrayList 进行反向迭代给出 IndexOutOfBoundsException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/580269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:29:23  来源:igfitidea点击:

Reverse iteration through ArrayList gives IndexOutOfBoundsException

javaarraylistiterationreverse

提问by Ankur

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:

当我反向迭代一个 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));
}


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

此外,如果有人知道反向迭代的更好习语,我很乐意尝试一下。

采纳答案by David Z

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

开始迭代,list.size() - 1因为数组(或ArrayList)元素的编号从 0 到 1 小于列表的大小。这是一个相当标准的习语:

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

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

请注意,您的前向迭代有效,因为它到达之前停止list.size()

回答by Coxy

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

Java 数组是零索引的。您必须设置 j = list.size() - 1 并继续直到 j = 0。

回答by Clint

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

list.size() 超过了最后一个允许的索引。

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

回答by Sualeh Fatehi

Avoid indexes altogether? How about:

完全避免索引?怎么样:

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

回答by Snailer

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?

我知道这是一个老问题,但 Java 包含一个Collections.reverse( List<T> )方法。为什么不直接反转它并进行前向迭代?

回答by el fuego

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) {
    ...
}

回答by Tobb

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.

如果名单是相当小的,这样的表现是不是一个真正的问题,一个可以使用reverse的的-metodLists在-class 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);

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:

这意味着 myList 的反向迭代可以写成:

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

回答by Dharmbir Singh

You can reverse by one line that is

您可以通过一行反转

Collections.reverse(list);

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]

回答by Gopala Krishna

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

如果您对 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());
}