102

现在,我有一个包含一段代码的程序,如下所示:

while (arrayList.iterator().hasNext()) {
     //value is equal to a String value
     if( arrayList.iterator().next().equals(value)) {
          // do something 
     }
}

就遍历 ArrayList 而言,我做得对吗?

我得到的错误是:

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.get(Unknown Source)
    at main1.endElement(main1.java:244)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at main1.traverse(main1.java:73)
    at main1.traverse(main1.java:102)
    at main1.traverse(main1.java:102)
    at main1.main(main1.java:404)

我会展示其余的代码,但它非常广泛,如果我没有正确地进行迭代,我会假设唯一的可能性是我没有ArrayList正确初始化。

4

8 回答 8

230

就遍历 Arraylist 而言,我做得对吗?

不:通过在每次迭代中调用iterator两次,你总是得到新的迭代器。

编写此循环的最简单方法是使用for-each构造:

for (String s : arrayList)
    if (s.equals(value))
        // ...

至于

java.lang.ArrayIndexOutOfBoundsException: -1

您刚刚尝试-1从数组中获取元素编号。计数从零开始。

于 2011-07-14T22:31:38.437 回答
142

虽然我同意接受的答案通常是最好的解决方案并且绝对更容易使用,但我注意到没有人展示了迭代器的正确用法。所以这里是一个简单的例子:

Iterator<Object> it = arrayList.iterator();
while(it.hasNext())
{
    Object obj = it.next();
    //Do something with obj
}
于 2012-09-19T18:29:19.227 回答
37
List<String> arrayList = new ArrayList<String>();
for (String s : arrayList) {
    if(s.equals(value)){
        //do something
    }
}

或者

for (int i = 0; i < arrayList.size(); i++) {
    if(arrayList.get(i).equals(value)){
        //do something
    }
}

但要小心ArrayList 可以保存空值。所以比较应该是

value.equals(arrayList.get(i))

当您确定该值不为空时,或者您应该检查给定元素是否为空。

于 2011-07-14T22:34:09.503 回答
10

你也可以这样使用:

for(Iterator iterator = arrayList.iterator(); iterator.hasNext();) {
x = iterator.next();
//do some stuff
}

投射和使用对象是一个很好的做法。例如,如果“arrayList”包含“Object1”对象的列表。然后,我们可以将代码重写为:

for(Iterator iterator = arrayList.iterator(); iterator.hasNext();) {
x = (Object1) iterator.next();
//do some stuff
}
于 2013-04-15T15:03:34.183 回答
8

您也可以像处理数组一样执行 for 循环,但您可以使用 list.get(i) 而不是 array[i]

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
于 2011-07-14T22:36:32.333 回答
7

除了 larsmans 的回答(谁确实是正确的),调用 get() 方法的异常,所以你发布的代码不是导致错误的代码。

于 2011-07-14T22:35:35.063 回答
4

ArrayList通过此链接迭代您的有效方法。这种类型将提高迭代期间循环的性能

int size = list.size();

for(int j = 0; j < size; j++) {
    System.out.println(list.get(i));
}
于 2014-01-08T13:38:20.380 回答
2

使用迭代器进行迭代不是故障安全的,例如,如果在迭代器创建后将元素添加到集合中,那么它将引发并发修改异常。它也不是线程安全的,您必须使其在外部线程安全。

所以最好使用for循环的for-each结构。它至少是故障安全的。

于 2014-08-16T11:31:34.120 回答