迭代器上的next()方法如何工作?

时间:2017-12-06 19:37:56

标签: java iterator

我对迭代器上的next()方法有疑问。如果我将此行作为我的代码的一部分(arrayOfStrings size = 4):

Iterator<String> it = arrayOfStrings.iterator(); //arrayOfString is ArrayList<String>

while(it.hasNext()) {
    String e = it.next();
    System.out.println(e);
}

在第一次迭代中,迭代器开始指向索引为0的元素?或者像“index -1”?

我问,因为据我所知,next()方法返回集合中的下一个元素。

因此,如果在第一次迭代时,迭代器在调用next()时从索引0开始,它将返回索引1处的元素,并且我将无法对索引0处的元素执行任何操作?

3 个答案:

答案 0 :(得分:2)

next视为两个步骤。首先它获取迭代器中的下一个项目,然后它将指针递增以指向下一个项目。因此,当您创建一个新的迭代器时,它会被初始化以返回列表中的第一个项目(索引0)。

答案 1 :(得分:0)

您展示的代码将正确打印ArrayList所有元素it.next()电话会在第一次通话时也是第一个元素。此元素通常用索引0 表示。

请注意,您可能希望重命名arrayOfStrings,因为技术上它不是数组,它更像是List。用户可能因为名称而认为它是一个数组。

文档

在我看来,你是对的documentation of the method可能有点令人困惑,因为它太紧凑了:

  

返回迭代中的下一个元素。

然而,描述可能需要如此详细,因为Iterator是一个非常常用的界面,不仅适用于集合。我可以设想一个类,其中第一个迭代元素不应该是底层结构的第一个元素。例如,在给定点之前已经读取的某种流。所以基本上由实现类来决定第一个元素是什么。但对于集合来说,它确实是第一个元素(索引0)。

对于-每个

另请注意,您显示的迭代等同于扩展for循环(for-each)在Java中的工作方式。所以像

这样的语法
for (Item item : items) {
    ...
}

将被视为

Iterator<Item> iter = items.iterator();
while(iter.hasNext()) {
    Item item = iter.next();
    ...
}

实际上,这就是为什么你可以在扩展for循环中使用实现Iterable的所有内容的原因。

如果iter.next()跳过第一个元素,那么它会更加令人困惑。我的意思是名称 for-each 应该迭代所有元素。

解析

让我们仔细看看该方法是如何实现的。因此,我们将首先看到ArrayList#iterator的作用。看看它的source code

public Iterator<E> iterator() {
    return new Itr();
}

Itr类是ArrayListsource code)的私有类。 hereItr#next方法:

@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];
}

所以它本质上返回的是索引i处的元素,它是光标在调用方法时的位置。它也已经将光标前进一个,以便下次调用该方法。

但是由于以下原因,0隐式初始化了光标。

int cursor; // Default value for int is 0

因此,next的第一次调用确实会返回索引0处的元素,即第一个元素

答案 2 :(得分:0)

我想象迭代器工作方式的方法是将其视为放在索引之间的东西。因此,当调用第一个next()时,您可以返回存储在[0]索引下的值,并且在该调用之后,迭代器在索引[0]和[1]之间等待下一次调用,以便为您返回值在索引[1]。在第二个next()调用之后迭代器在[1]和[2]之间等待,等等......

这只是我习惯迭代器的方法,但它可能对你有所帮助。