Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList iterator not working when declared in loop

Tags:

java

Why is the first snip running in an endless loop while the second works?

//Initial code
ArrayList<String> myList = new ArrayList<String>();
myList.add("A");
myList.add("B");
myList.add("C");
myList.add("D");
myList.add("E");
while(myList.iterator().hasNext()) {
    System.out.println(myList.iterator().next());
}
System.out.println();



//Correct code
ArrayList<String> myList = new ArrayList<String>();
myList.add("A");
myList.add("B");
myList.add("C");
myList.add("D");
myList.add("E");
Iterator itr = myList.iterator();
while(itr.hasNext()) {
    System.out.println(itr.next());
}
System.out.println();
like image 614
Iulian Avatar asked Nov 30 '22 19:11

Iulian


2 Answers

Every time you call iterator() you get a new Iterator with its cursor at the first element. You're consuming the first element, but discarding the Iterator. You're just not moving forward.

like image 106
Sotirios Delimanolis Avatar answered Dec 09 '22 07:12

Sotirios Delimanolis


In the first version of the code a new instance of the Iterator is created during each iteration of the loop, because the ArrayList#iterator() method is invoked. Calling iterator() will return a new Iterator instance each time. I suspect you may be thinking iterator() works similar to a Java beans getXXXX accessor, however it does not.

//new Iterator Instance will always have a next item
//Iterator is a different instance during each iteration
while(myList.iterator().hasNext()) { 
    System.out.println(myList.iterator().next());
}
System.out.println();

The second version of the code assigns the Iterator to a variable, which causes the hasNext() method to be invoked on the same Iterator instance. Since this iterator instance has its .next() method invoked for each loop iteration it performs as you would expect and eventually ends the loop when hasNext returns false.

//Same instance of the iterator for each iteration
Iterator itr = myList.iterator();
while(itr.hasNext()) {
    System.out.println(itr.next());
}

In a nutshell

Iterator itr = myList.iterator();
Iterator itr2 = myList.iterator();
System.out.println(itr == itr2 ? "Same":"Different"); //outputs Different

It may also help you to see the source code for ArrayList#iterator:

 //notice how a new instance of the Nested Itr class is created
 public Iterator<E> iterator() {
     return new Itr(); 
 }
like image 39
Kevin Bowersox Avatar answered Dec 09 '22 08:12

Kevin Bowersox