当与java.util.Queue一起使用时,for语句中的迭代器.next()方法是什么?

当与java.util.Queue一起使用时,for语句中的迭代器.next()方法是什么?,java,for-loop,iterator,queue,next,Java,For Loop,Iterator,Queue,Next,例如: 公共类测试{ 公共静态void main(字符串[]args){ 队列名称=新的LinkedList(Arrays.asList(“First”、“Middle”、“Last”)); System.out.println(“循环前的队列:+名称”); System.out.println(“打印循环…”); for(迭代器i=names.Iterator();i.hasNext();){ 字符串名称=i.next(); System.out.println(名称); } System.o

例如:

公共类测试{
公共静态void main(字符串[]args){
队列名称=新的LinkedList(Arrays.asList(“First”、“Middle”、“Last”));
System.out.println(“循环前的队列:+名称”);
System.out.println(“打印循环…”);
for(迭代器i=names.Iterator();i.hasNext();){
字符串名称=i.next();
System.out.println(名称);
}
System.out.println(“循环后的队列:+名称”);
}
}
输出:

循环前的队列:[第一、中间、最后]
打印循环。。。
弗斯特
中间的
最后
循环后的队列:[第一、中间、最后]

我知道next()方法如何遍历LinkedList。但是当它在一个Queue.iterator()上被调用时,比如,
i.next()
它做什么

从输出中可以看到,它没有从队列中删除任何元素
我认为应该是这样的,因为队列只有
remove()/poll()

迭代器
仅用于对集合进行迭代。在这种情况下,您可以对每个结果使用一个:

for(String name : names){
  System.out.println(name);
}
但是,基于您的问题,我假设您希望迭代
队列
弹出,并以FIFO顺序打印每个项目(因此使用
链接列表
)。在这种情况下,您可能只需要循环
names.size()
次数,然后调用
.remove()
在每次迭代中弹出一个项目,如下所示:

for(int n = names.size(); n > 0; n--){
  String name = names.remove();
  System.out.println(name);
}
输出:

循环前的队列:[第一、中间、最后]
打印循环。。。
弗斯特
中间的
最后
循环后的队列:[]


编辑:要进一步解释
.iterator()
,请执行以下操作:

如果我们看,我们可以看到它是一个接口。每个集合实现都有自己的迭代器实现。
请看,
iterator()
方法如下:

/**
*返回一个迭代器,该迭代器按FIFO顺序遍历此队列中的项。
*
*@返回一个迭代器,该迭代器按FIFO顺序遍历此队列中的项目
*/
公共迭代器迭代器(){
返回新的ListIterator();
}
//迭代器不实现remove(),因为它是可选的
私有类ListIterator实现了迭代器{
private Node current=first;//包含当前项的节点
公共布尔hasNext(){
返回电流!=null;
}
公共空间删除(){
抛出新的UnsupportedOperationException();
}
公共项目下一步(){
如果(!hasNext())抛出新的NoSuchElementException();
项目=当前项目;
当前=当前。下一步;
退货项目;
}
}
如您所见,当在
iterator()
方法中创建
ListIterator
时,它将队列的
节点首先存储为其
当前的

在实际的
next()
-方法中,它既不使用队列的
remove()
也不使用
poll()
方法(也不使用
get()
),因此实际上不会弹出项目。相反,它只是将当前节点临时存储为
Item Item=current.Item
;然后使用
current=current.next将
current
节点更新到下一个节点;之后,它将返回该临时

因为
names
是LinkedList对象,而LinkedList没有 其中的任何
iterator()
方法,
names.iterator()
将调用 (LinkedList的直接超类)

但是,通过在初始化
i=names.iterator()
时跟踪调用堆栈(可以通过任何合适的java IDE的GUI调试器轻松完成),可以很容易地看到它调用了方法
listIterator(0)
方法。尽管AbstractList有自己的
listIterator(int-index)
实现,但LinkedList有


LinkedList.java的段:

跟踪,到迭代器接下来指向的位置

这在考虑服务器的性能时起作用


用于增强for循环的Oracle文档片段:

正如您所看到的,它使用了
#i.next()
方法,并且由于
名称
(在原始问题的示例中)是队列类型的变量,因此可以在黑暗中假设
#i。next()
在增强for循环中使用了AbstractList中的实现,并且它无疑地使用了一些
get(int index)
方法,因此性能很差(像我这样一个可怜、不幸的家伙,做了同样的推断,陷入了一堆代码中。LOL)

关于这个错误的推论,我在这个论坛上问了这个问题,在深入挖掘了几天之后,现在我发现使用增强的for循环迭代LinkedList对象时,没有任何性能降低(据我所知)

该迭代器对象(
#i
)使用变量
Node next
保留对下一个对象的引用,以便在增强for循环的下一次迭代中使用


为什么你认为它会去除任何元素?您从未调用过
remove()
。您可以将
迭代器看作是指向集合中特定元素的指针。调用
i.next()
时,指针移动一个元素并指向另一个元素。@Amongalen因为我假设
Queue
只有
remove()/poll()
方法来获取所有存储的值/对象。因此,
队列对象的迭代器如何在不更改
队列
名称的情况下遍历它?另外,如果
next()
队列对象上使用指针
获取第n个元素的方法是什么?我知道我可以使用你的建议,我已经使用过了。我想知道这个java nat是如何实现的
package java.util;

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{   
    public ListIterator<E> listIterator(int index) {
            checkPositionIndex(index);
            return new ListItr(index);
    }
    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned = null;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;
        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }
        public boolean hasNext() {
            return nextIndex < size;
        }
        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();
            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }
    *
    *   (code contraction...)
    *
        final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
    }
}
private Node<E> next;
for (I #i = Expression.iterator(); #i.hasNext(); ) {
    VariableModifiersopt TargetType Identifier = (TargetType) #i.next();
    Statement
}