2011-07-14 40 views
102

Ngay bây giờ, tôi có một chương trình có chứa một đoạn mã mà trông như thế này:ArrayIndexOutOfBoundsException khi sử dụng iterator của ArrayList

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

Tôi có làm đúng đó, như xa như lặp lại qua ArrayList đi?

Các lỗi tôi nhận được là:

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) 

tôi sẽ hiển thị phần còn lại của mã này, nhưng nó khá rộng, và nếu tôi không làm lặp đi lặp lại một cách chính xác, tôi sẽ giả định khả năng duy nhất là Tôi không khởi tạo đúng cách ArrayList.

+0

Trong java 8, bạn có thể sử dụng phương thức 'forEach': http://stackoverflow.com/questions/16635398/java-8-iterable-foreach-vs-foreach-loop –

Trả lời

228

Tôi có làm đúng, theo như lặp qua Danh sách không?

Không: bằng cách gọi iterator hai lần trong mỗi lần lặp lại, bạn sẽ nhận được trình lặp mới tất cả thời gian.

Cách dễ nhất để viết vòng lặp này được sử dụng for-each xây dựng:

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

Đối với

java.lang.ArrayIndexOutOfBoundsException: -1

Bạn chỉ cần cố gắng để có được yếu tố số -1 từ một mảng . Đếm bắt đầu từ số không.

+1

Sử dụng cho mỗi, nó dễ dàng hơn nhiều. Ngoài ra nó có thể bạn gọi là arrayList.iterator(). Next() một lần nữa và bỏ qua các mục. –

+0

@ larsmans Ah cảm ơn bạn rất nhiều. Tôi hoàn toàn quên bạn có thể làm điều đó với danh sách mảng. Tuy nhiên, tôi đã thử với mã của tôi, và tôi vẫn nhận được lỗi tương tự. Vì vậy, tôi nghĩ rằng đó là một vấn đề với cách tôi thêm vào arrayList trước đó trong mã, vì vậy bây giờ tôi sẽ xem xét địa chỉ đó. Tuy nhiên, cảm ơn bạn rất nhiều vì đã nhắc tôi về điều đó. –

+0

yêu thích điều đó đối với mỗi nhà điều hành. Tôi sử dụng một cái gì đó giống như nó trong ruby ​​tất cả các thời gian ... 'do array.each | s | trừ khi (s.nil?) kết thúc kết thúc' –

37
List<String> arrayList = new ArrayList<String>(); 
for (String s : arrayList) { 
    if(s.equals(value)){ 
     //do something 
    } 
} 

hoặc

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

Nhưng hãy cẩn thận ArrayList có thể giữ giá trị null. Vì vậy, so sánh phải là

value.equals(arrayList.get(i)) 

khi bạn chắc chắn rằng giá trị đó không phải là rỗng hoặc bạn nên kiểm tra xem phần tử đã cho có rỗng hay không.

+0

Cảm ơn bạn đã nhập. :) –

7

Ngoài câu trả lời của larsmans (thực sự là đúng), ngoại lệ trong cuộc gọi đến phương thức get(), vì vậy mã bạn đã đăng không phải là lỗi gây ra lỗi.

8

Bạn cũng có thể làm một vòng lặp for như bạn muốn cho một mảng nhưng thay vì mảng [i] bạn sẽ sử dụng list.get (i)

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

khi tôi đồng ý rằng câu trả lời chấp nhận thường là giải pháp tốt nhất và chắc chắn dễ sử dụng hơn, tôi nhận thấy không có ai hiển thị việc sử dụng thích hợp của trình lặp. Vì vậy, đây là một ví dụ nhanh:

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

Tôi cảm thấy câu trả lời này chính xác hơn, vì đây là một ví dụ về trình lặp thay vì giải pháp thay thế. – withoutclass

+1

Cảm ơn bạn đã phản hồi sâu sắc. cho (...) lặp lại là * thường là * giải pháp tốt nhất, nhưng không phải lúc nào cũng vậy. Hôm nay, tôi tình cờ tìm kiếm cú pháp iterator được quản lý rõ ràng và ở đây nó được. –

+1

câu trả lời hay và hữu ích. – Fattie

10

Bạn cũng có thể sử dụng như thế này:

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

nó một thực hành tốt để đúc và sử dụng đối tượng. Ví dụ: nếu 'arrayList' chứa danh sách đối tượng 'Object1'.Sau đó, chúng ta có thể viết lại các mã như:

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

cách hiệu quả để lặp của bạn ArrayList Tiếp theo link này. Loại này sẽ cải thiện hiệu suất của vòng lặp trong lặp

int size = list.size(); 

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

lặp lại sử dụng iterator là không thất bại an toàn ví dụ nếu bạn thêm yếu tố để các bộ sưu tập sau khi tạo iterator của sau đó nó sẽ ném concurrentmodificaionexception. Ngoài ra nó không phải là thread an toàn, bạn phải làm cho nó thread an toàn bên ngoài.

Vì vậy, tốt hơn nên sử dụng cấu trúc cho mỗi vòng lặp. Đó là ít nhất không an toàn.

Các vấn đề liên quan