简体   繁体   中英

ArrayList iterator not working when declared in loop

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(); 
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM