102

Right now, I have a program containing a piece of code that looks like this:

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

Am I doing that right, as far as iterating through the ArrayList goes?

The error I am getting is:

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)

I would show the rest of the code, but it's pretty extensive, and if I am not doing the iteration correctly, I would assume the only possibility is that I am not initializing the ArrayList properly.

Makoto
  • 104,088
  • 27
  • 192
  • 230
This 0ne Pr0grammer
  • 2,632
  • 14
  • 57
  • 81

8 Answers8

229

Am I doing that right, as far as iterating through the Arraylist goes?

No: by calling iterator twice in each iteration, you're getting new iterators all the time.

The easiest way to write this loop is using the for-each construct:

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

As for

java.lang.ArrayIndexOutOfBoundsException: -1

You just tried to get element number -1 from an array. Counting starts at zero.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 1
    Use for-each, it's much easier. Also it's possible you called arrayList.iterator().next() again and skipped entries. –  Jul 14 '11 at 22:34
  • @ larsmans Ah thank you very much. I totally forgot you could do that with array List. However, I tried that with my code, and I still am getting the same error. So I think it's a problem with how I am adding to the arrayList earlier in the code, so I will now look at address that. Still, thank you very much for reminding me about that. – This 0ne Pr0grammer Jul 14 '11 at 22:38
  • love that for each operator. I use something like it in ruby all the time... `do array.each |s| unless (s.nil?) end end` – David West Oct 21 '12 at 18:12
  • 2
    Just to note, `Have you heard of` seems kind of offensive (for no reason), but I'm not native. Otherwise great. – n611x007 Dec 09 '12 at 12:53
  • 3
    @naxa: it may come over as condescending, I've changed the wording. – Fred Foo Dec 09 '12 at 14:56
142

While I agree that the accepted answer is usually the best solution and definitely easier to use, I noticed no one displayed the proper usage of the iterator. So here is a quick example:

Iterator<Object> it = arrayList.iterator();
while(it.hasNext())
{
    Object obj = it.next();
    //Do something with obj
}
NemesisX00
  • 2,046
  • 2
  • 13
  • 12
  • 12
    I feel like this more accurately answers the question, since it's an iterator example instead of an alternative solution. – withoutclass Apr 15 '13 at 15:51
  • 1
    Thank you for your insightful response. for(...) iteration is *usually* the best solution, but not always. Today, I happen to be looking for explicitly managed iterator syntax and here it is. – Robert Altman Jan 15 '14 at 16:29
37
List<String> arrayList = new ArrayList<String>();
for (String s : arrayList) {
    if(s.equals(value)){
        //do something
    }
}

or

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

But be carefull ArrayList can hold null values. So comparation should be

value.equals(arrayList.get(i))

when you are sure that value is not null or you should check if given element is null.

Paul T.
  • 714
  • 1
  • 9
  • 20
zacheusz
  • 8,750
  • 3
  • 36
  • 60
10

You can also use like this:

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

Its a good practice to cast and use the object. For example, if the 'arrayList' contains a list of 'Object1' objects. Then, we can re-write the code as:

for(Iterator iterator = arrayList.iterator(); iterator.hasNext();) {
x = (Object1) iterator.next();
//do some stuff
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
subbu
  • 524
  • 6
  • 16
8

You could also do a for loop as you would for an array but instead of array[i] you would use list.get(i)

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
Stas Jaro
  • 4,747
  • 5
  • 31
  • 53
7

Apart of larsmans answer (who is indeed correct), the exception in a call to a get() method, so the code you have posted is not the one that is causing the error.

SJuan76
  • 24,532
  • 6
  • 47
  • 87
4

Efficient way to iterate your ArrayList followed by this link. This type will improve the performance of looping during iteration

int size = list.size();

for(int j = 0; j < size; j++) {
    System.out.println(list.get(i));
}
Patt Mehta
  • 4,110
  • 1
  • 23
  • 47
RED.Skull
  • 1,696
  • 3
  • 24
  • 49
2

iterating using iterator is not fail-safe for example if you add element to the collection after iterator's creation then it will throw concurrentmodificaionexception. Also it's not thread safe, you have to make it thread safe externally.

So it's better to use for-each structure of for loop. It's atleast fail-safe.

Sumit Kumar Saha
  • 799
  • 1
  • 12
  • 25