ArrayList의 반복자를 사용할 때 ArrayIndexOutOfBoundsException 발생


103

지금은 다음과 같은 코드가 포함 된 프로그램이 있습니다.

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에서 당신은 사용할 수 있습니다 forEach: 방법 stackoverflow.com/questions/16635398/...
Vitalii Fedorenko

답변:


229

Arraylist를 반복하는 한 내가 올바르게하고 있습니까?

아니오 : iterator각 반복에서 두 번 호출 하면 항상 새 반복자를 얻습니다.

이 루프를 작성하는 가장 쉬운 방법은 for-each 구문을 사용하는 것 입니다 .

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

에 관해서

java.lang.ArrayIndexOutOfBoundsException: -1

방금 -1배열에서 요소 번호를 얻으려고했습니다 . 계산은 0에서 시작됩니다.


1
for-each를 사용하면 훨씬 쉽습니다. 또한 arrayList.iterator (). next ()를 다시 호출하고 항목을 건너 뛸 수 있습니다.

@ larsmans 아 정말 감사합니다. 배열 목록으로 할 수 있다는 것을 완전히 잊었습니다. 그러나 내 코드로 시도했지만 여전히 동일한 오류가 발생합니다. 그래서 코드의 앞부분에서 arrayList에 추가하는 방법에 문제가 있다고 생각하므로 이제 주소를 살펴 보겠습니다. 그래도 그것에 대해 상기시켜 주셔서 대단히 감사합니다.
이 0ne Pr0grammer jul.

각 연산자를 좋아합니다. 나는 ... 모든 루비의 시간을 그와 같은 것을 사용 do array.each |s| unless (s.nil?) end end
데이비드 웨스트

2
참고로, Have you heard of약간 불쾌감을주는 것 같지만 (이유없이) 저는 원주민이 아닙니다. 그렇지 않으면 좋습니다.
n611x007

3
@naxa : 내키는대로 올 수 있습니다. 문구를 변경했습니다.
Fred Foo

142

허용되는 답변이 일반적으로 최상의 솔루션이고 확실히 사용하기 쉽다는 데 동의하지만 아무도 반복자의 적절한 사용법을 표시하지 않았습니다. 여기에 간단한 예가 있습니다.

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

12
대체 솔루션이 아닌 반복기 예제이기 때문에 질문에 더 정확하게 대답하는 것 같습니다.
withoutclass

1
귀하의 통찰력있는 답변에 감사드립니다. for (...) 반복은 일반적 으로 최상의 솔루션이지만 항상 그런 것은 아닙니다. 오늘 저는 명시 적으로 관리되는 반복기 구문을 찾고 있는데 여기에 있습니다.
Robert Altman 2014 년

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는 null 값을 보유 할 수 있습니다 . 따라서 비교는

value.equals(arrayList.get(i))

값이 null이 아니라고 확신하거나 주어진 요소가 null인지 확인해야합니다.


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
}

8

배열에 대해하는 것처럼 for 루프를 수행 할 수도 있지만 array [i] 대신 list.get (i)를 사용합니다.

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

7

larsmans 답변 (실제로 올바른 사람) 외에도 get () 메서드 호출의 예외이므로 게시 한 코드가 오류를 일으키는 코드가 아닙니다.


4

ArrayList링크를 따라가는 효율적인 방법 . 이 유형은 반복 중 루핑 성능을 향상시킵니다.

int size = list.size();

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

2

반복기를 사용하여 반복하는 것은 안전하지 않습니다. 예를 들어 반복자가 생성 된 후 컬렉션에 요소를 추가하면 동시 수정 예외가 발생합니다. 또한 스레드로부터 안전하지 않으므로 외부에서 스레드로부터 안전하게 만들어야합니다.

따라서 for 루프의 for-each 구조를 사용하는 것이 좋습니다. 최소한 안전 장치입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.