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();
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.
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With