【问题标题】:ArrayIndexOutOfBoundsException when using the ArrayList's iterator [duplicate]使用 ArrayList 的迭代器时出现 ArrayIndexOutOfBoundsException [重复]
【发布时间】:2011-10-05 18:07:45
【问题描述】:

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

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

【问题讨论】:

标签: java arraylist iterator indexoutofboundsexception


【解决方案1】:

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

否:通过在每次迭代中调用 iterator 两次,您一直在获得新的迭代器。

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

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

至于

java.lang.ArrayIndexOutOfBoundsException: -1

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

【讨论】:

  • 使用 for-each 会容易得多。您也有可能再次调用 arrayList.iterator().next() 并跳过条目。
  • @larsmans 啊,非常感谢。我完全忘记了你可以用数组列表来做到这一点。但是,我用我的代码尝试过,但我仍然遇到同样的错误。所以我认为这是我如何在代码前面添加到 arrayList 的问题,所以我现在将看看解决这个问题。不过,非常感谢你提醒我。
  • 喜欢每个操作员。我一直在 ruby​​ 中使用类似的东西...do array.each |s| unless (s.nil?) end end
  • 请注意,Have you heard of 似乎有点冒犯(无缘无故),但我不是本地人。否则很棒。
  • @naxa:它可能会显得居高临下,我已经改变了措辞。
【解决方案2】:

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

Iterator<Object> it = arrayList.iterator();
while(it.hasNext())
{
    Object obj = it.next();
    //Do something with obj
}

【讨论】:

  • 我觉得这更准确地回答了这个问题,因为它是一个迭代器示例而不是替代解决方案。
  • 感谢您富有洞察力的回复。 for(...) 迭代通常是最好的解决方案,但并非总是如此。今天,我碰巧在寻找显式管理的迭代器语法,就在这里。
【解决方案3】:
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))

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

【讨论】:

    【解决方案4】:

    你也可以这样使用:

    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
    }
    

    【讨论】:

      【解决方案5】:

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

      for (int i = 0; i < list.size(); i++) {
          System.out.println(list.get(i));
      }
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          迭代您的ArrayList 后跟此link 的有效方法。这种类型会提高迭代过程中循环的性能

          int size = list.size();
          
          for(int j = 0; j < size; j++) {
              System.out.println(list.get(i));
          }
          

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              猜你喜欢
              • 2020-06-20
              • 2016-08-31
              • 1970-01-01
              • 2014-08-14
              • 1970-01-01
              • 1970-01-01
              • 2021-11-16
              • 2013-07-15
              • 1970-01-01
              相关资源
              最近更新 更多