ArrayIndexOutOfBoundsException при использовании итератора ArrayList - PullRequest
102 голосов
/ 15 июля 2011

Прямо сейчас, у меня есть программа, содержащая фрагмент кода, который выглядит следующим образом:

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.

Ответы [ 8 ]

228 голосов
/ 15 июля 2011

Правильно ли я делаю это, что касается итерации Arraylist?

Нет: вызывая iterator дважды в каждой итерации, вы получаете новые итераторы всевремя.

Самый простой способ написать этот цикл - использовать конструкцию for-each :

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

Что касается

java.lang.ArrayIndexOutOfBoundsException: -1

Вы только что попытались получить номер элемента -1 из массива.Отсчет начинается с нуля.

141 голосов
/ 19 сентября 2012

Хотя я согласен, что принятый ответ, как правило, является лучшим решением и определенно проще в использовании, я заметил, что никто не отображал правильное использование итератора.Итак, вот небольшой пример:

Iterator<Object> it = arrayList.iterator();
while(it.hasNext())
{
    Object obj = it.next();
    //Do something with obj
}
37 голосов
/ 15 июля 2011
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))

когда вы уверены, что значение не является нулевым, или вам следует проверить, является ли данный элемент нулевым.

10 голосов
/ 15 апреля 2013

Вы также можете использовать так:

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
}
8 голосов
/ 15 июля 2011

Вы также можете сделать цикл for, как для массива, но вместо массива [i] вы бы использовали list.get (i)

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
7 голосов
/ 15 июля 2011

Кроме ответа larsmans (который действительно прав), исключение при вызове метода get (), поэтому отправленный вами код не тот, который вызывает ошибку.

4 голосов
/ 08 января 2014

Эффективный способ итерации вашего ArrayList, за которым следует ссылка . Этот тип улучшит производительность цикла во время итерации

int size = list.size();

for(int j = 0; j < size; j++) {
    System.out.println(list.get(i));
}
2 голосов
/ 16 августа 2014

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

Так что лучше использовать структуру for-each для цикла for.Это как минимум отказоустойчиво.

...