ArrayIndexOutOfBoundsException при использовании Итератора ArrayList

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

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 правильно.

Ответ 1

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

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

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

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

Что касается

java.lang.ArrayIndexOutOfBoundsException: -1

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

Ответ 2

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

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

Ответ 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))

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

Ответ 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, как и для массива, но вместо массива [i] вы должны использовать list.get(i)

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

Ответ 6

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

Ответ 7

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

int size = list.size();

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

Ответ 8

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

Поэтому лучше использовать для каждой структуры цикла for. Это по крайней мере безопасно.