Java linklist.iterator().next()如何工作?
我试图理解迭代器在第一个元素的情况下是如何工作的。 就像我们第一次调用iterator.next()时一样,为什么它返回0索引而不是1? 有一个类似的线程在某种程度上回答了这个问题,但它本身的代码似乎并不匹配。 通过这段代码,似乎下一个方法实际上返回当前元素并将光标移动到下一个元素Java linklist.iterator().next()如何工作?,java,iterator,Java,Iterator,我试图理解迭代器在第一个元素的情况下是如何工作的。 就像我们第一次调用iterator.next()时一样,为什么它返回0索引而不是1? 有一个类似的线程在某种程度上回答了这个问题,但它本身的代码似乎并不匹配。 通过这段代码,似乎下一个方法实际上返回当前元素并将光标移动到下一个元素 @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
那么,思考这种方法的正确方法是什么呢?
我是否应该忽略java文档,将其视为返回当前值并移动到下一个?
cursor
初始化为0
,并且由于next()
返回索引为cursor
的元素(递增cursor
之前的值,存储在i
中),对next()
的第一个调用返回第一个元素(索引0
)
这个迭代器的不变量是游标
始终保存下一个元素的索引。
因此,每次调用next()
都会返回索引为cursor
的元素,并递增cursor
就像我们第一次调用iterator.next()时一样,为什么
返回0索引而不是1
因为如果列表的迭代器不允许您遍历基础列表的所有元素,那么它们将有严重的缺陷
那么,思考这种方法的正确方法是什么呢?我应该吗
只需忽略java文档,并将其视为return current和move
下一个
不,你的心理模型与文档不一致,你应该首先考虑你的模型是否需要调整。在这种情况下,您可能会得到更好的模型:
- 对于任何迭代器,都可能有一个它将迭代的空项目序列。
方法返回迭代器尚未返回的下一个next()
- 由于它适用于
,因此,将迭代器视为具有当前元素是毫无帮助的。它有下一个元素(可能)和上一个元素(可能),但没有当前元素。可以将其视为指向元素之间、第一个元素之前或最后一个元素之后列表
- 因为当您还没有看到任何元素时,第一个元素是“下一个”。迭代器的初始位置在第一个元素前面
考虑一下商店里的柜台。柜台后面有一位店员,但他还没有接待任何顾客。顾客出现并排成一行
没有“当前”客户。没有人得到服务
该员工现在已准备好接待客户,并呼叫“请接下一位客户”。排在队伍前面的人向前走。他/她现在是“当前”客户。我看不出与文档有冲突。也许你不理解这个上下文中的“下一个”这个词。它的意思是“下一个可用的数据”。因此,当没有读取以前的项目时,下一个可用的项目就是第一个项目。在您发布的代码中,没有任何内容表明
光标
指向“当前”元素。你在心理上将光标和当前光标等同起来,但事实并非如此<代码>游标只是实现细节,不会影响迭代器的接口。实现者本可以选择将其初始化为-1并相应地更改实现,但显然发现这种方法更简单。谢谢!因此,在第二点上进行扩展时,我们会认为当我们初始化迭代器时,它指向该列表的第一个元素作为下一个元素/光标,但迭代器本身在列表前“悬停”并指向它不会错?@Kirill.bpp,是的,这是一种合理的思考方式。另外,当我编写迭代器时,我的变量名比您介绍的代码中的变量名更清楚。“cursor”这个名称解释了变量的性质,但不是它的意义,我可能会选择更像“nextElementIndex”的名称。