在循环中声明时,ArrayList迭代器不起作用

Iul*_*ian 4 java

为什么第一个剪辑在无限循环中运行而第二个剪辑有效?

//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();
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 11

每次你打电话时iterator(),你得到一个新的 Iterator,其光标放在第一要素.你正在消耗第一个元素,但丢弃了Iterator.你只是没有前进.

  • 我不得不给你下一次投票给好的答案徽章! (2认同)

Kev*_*sox 8

在代码的第一个版本中,在循环的每次迭代期间创建了一个新实例Iterator,因为ArrayList#iterator()调用了该方法.每次调用iterator()都会返回一个新Iterator实例.我怀疑你可能在想iterator()类似于Java bean getXXXX访问器的工作,但事实并非如此.

//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();
Run Code Online (Sandbox Code Playgroud)

代码的第二个版本将Iterator变量分配给变量,这会导致hasNext()在同一Iterator实例上调用该方法.由于此迭代器实例已.next()为每个循环迭代调用其方法,因此它会按预期执行,并在hasNext返回false 时最终结束循环.

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

简而言之

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

它也可以帮助你看到的源代码为ArrayList#iterator:

 //notice how a new instance of the Nested Itr class is created
 public Iterator<E> iterator() {
     return new Itr(); 
 }
Run Code Online (Sandbox Code Playgroud)