当与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
}