2

迭代器保证有以下方法:

  • 有下一个()
  • 下一个()
  • 删除(可选

for-each循环遍历iterable类对象时,它如何知道从哪个对象开始?上述方法提供了清晰的前进路径,但什么指向起始元素?

For-each保证遍历所有相关对象。根据一个类及其next()实现,从哪里开始可能非常重要(考虑forward linked list或任何其他具有root元素的实现)。

它是如何工作的?

如果我的问题没有意义,请解释原因。

4

4 回答 4

2

您可能想查看内部类的ArrayList实现。IteratorItr

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

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

cursor默认初始化为0。您用于cursor访问ArrayList对象的支持数组中的元素(它是一个内部类,它可以访问该字段)。

类似的逻辑适用于Iterator. 它始终取决于底层数据结构。作为另一个例子, aSet不应该有一个排序,但它确实实现了Iterator. 必须决定迭代器从哪里开始。

于 2013-09-24T22:51:17.320 回答
2

从规范:

官方称为增强for语句( for(E e: Iterable<E> iterable)) 的内容由编译器翻译成等效于以下代码:

E e;
for(Iterator<E> it = iterable.iterator(); it.hasNext(); ) {
    e = it.next();
    // contents of your for loop
}

循环的行为就像你用一个明确的 编写它一样,所以增强循环Iterator的“起点”是无论如何都应该开始的地方。foriterable.iterator()

于 2013-09-24T23:09:19.317 回答
0

foreach 是从 first 到 last 的 for 循环的简写。

于 2013-09-24T22:51:05.667 回答
0

这一切都取决于您的收藏。

如果您的集合是一个列表(ArrayListLinkedList通常),那么迭代器将根据它们的插入方式按列表顺序排列。

如果是 Map 或 Set,则很难预测其成员的顺序。如果您使用的是 Map 或 Set,则实际上不应指望任何可预测的排序,因为它不符合这些集合的目的。但是,如果您需要特定订单但还需要 Map 或 Set 的功能,则可以使用 or LinkedHashMapLinkedHashSet

于 2013-09-24T22:54:39.300 回答