例如:
public class Test {
public static void main(String[] args) {
Queue<String> names = new LinkedList<>(Arrays.asList("First", "Middle", "Last"));
System.out.println("Queue before the loop: " + names);
System.out.println("Printing loop...");
for (Iterator<String> i = names.iterator(); i.hasNext();) {
String name = i.next();
System.out.println(name);
}
System.out.println("Queue after the loop: " + names);
}
}
输出:
Queue before the loop: [First, Middle, Last]
Printing loop...
First
Middle
Last
Queue after the loop: [First, Middle, Last]
我知道next()方法如何遍历 LinkedList。但是当它在 * Queue.iterator()* 上被调用时,比如i.next()
,它会做什么?
从输出中可以看到,它没有从队列中删除任何元素。
- 我认为应该是这样,因为队列只有
remove()/poll()
。*
2条答案
按热度按时间iyr7buue1#
Iterator
只是用来遍历一个Collection。在这种情况下,您可以使用for-each来获得相同的结果:然而,根据你的问题,我假设你想迭代
Queue
,***弹出***并以FIFO顺序打印每个项目(因此使用你的LinkedList
)。在这种情况下,您可能只需要循环names.size()
次,并调用.remove()
在每次迭代中弹出一个项,如下所示:输出:
在线试用
编辑:为了解释更多关于
.iterator()
的内容:如果我们看the source code of the
Iterator
,我们可以看到它是一个接口。每个集合实现都有自己的Iterator实现。查看the source code of the
Queue
,iterator()
方法如下:正如您所看到的,当在
iterator()
方法中创建ListIterator
时,它将Queue的Node first
存储为其current
。在实际的
next()
-方法中,它既不使用Queue的remove()
方法,也不使用poll()
方法(也不使用get()
..),因此实际上并没有弹出这些项。相反,它只是用Item item = current.item
临时存储当前Node;然后将current
节点更新到下一个current = current.next
节点;之后它将返回临时item
。1aaf6o9v2#
由于
names
是一个 LinkedList 对象,并且 LinkedList 中没有任何iterator()
方法,因此names.iterator()
将在 AbstractSequentialList(LinkedList 的直接超类)中调用该方法。然而,通过跟踪调用堆栈 (可以通过任何像样的java IDE的GUI调试器轻松完成),当初始化
i = names.iterator()
时,可以很容易地看到它在这里调用了listIterator(0)
方法。即使 AbstractList 有自己的listIterator(int index)
实现,LinkedList 也覆盖了相同的方法;因此,显然
names.iterator()
将通过return new ListItr(index)
返回一个对象,return new ListItr(index)
是 LinkedList 的内部类。现在我们可以清楚地看到,在调用
i.next()
时,它实际上调用了内部类***ListItr***中的next()
方法。它还使用类变量;跟踪迭代器接下来要指向的地方。
这在考虑增强的for循环的性能时起作用。
正如您所看到的,这使用了
#i.next()
方法,由于names
(在原始问题的示例中)是一个类型为*Queue*的变量,可以在黑暗中假设增强for循环中的#i.next()
使用了 AbstractList 中的此实现,并且它可疑地使用了一些get(int index)
方法,因此性能较差(一个像我一样可怜的不幸的人,做了同样的推导,陷入了一堆代码中。LOL)。关于那个错误的推论,我在这个论坛上问了这个问题,经过几天的深入挖掘,现在我可以看到,当使用增强的for循环迭代 LinkedList 对象时,没有任何性能降低(据我所知没有),因为事实是,
#i
)使用变量Node<E> next
来保持对下一个对象的引用,以便在 enhanced-for-loop 的下一次迭代中使用。