2013-09-24 55 views
1

迭代保证具有以下方法:for-each循环如何知道从哪里开始?

  • hasNext()
  • 下()
  • 删除(可选

for-each循环迭代通过iterable类对象,它如何知道对象开始与?上述方法提供了明确的路径,但是什么指向了起点?

For-each保证迭代通过全部相关对象。根据类别及其实现,从何处开始可能至关重要(考虑forward linked list或具有root元素的任何其他实现)。

它是如何工作的?

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

+0

它使用任何'next()'在第一次迭代时返回... –

+0

您从容器获取的迭代器被初始化为开始。 – andy256

+0

您可以在'Iterator'实现中定义从哪里开始。例如,对于'List',你有一个* straight *迭代器,它从第一个元素到最后一个元素,以及一个从最后一个元素到最后一个元素的反向迭代器。 –

回答

2

From the spec:

什么正式名称叫增强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,所以增强的for循环的“起点”是无论如何都会启动iterable.iterator()的任何地方。

0

foreach是循环从第一个到最后一个的简写。

+0

定义“* first *”和“* last *”的定义类是不是从Java'Collection'派生的定义类? –

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的其他实现。它总是依赖于底层的数据结构。作为另一个例子,Set不应该有排序,但它确实实现了Iterator。必须做出关于迭代器开始的地方的决定。

0

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

如果您的收藏是列表(通常为ArrayListLinkedList),那么迭代器将根据它们的插入顺序进入列表顺序。

如果它是一个Map或Set,很难预测其成员的顺序。如果您使用的是Map或Set,实际上,您不应该依赖任何可预测的排序,因为它不符合这些集合的用途。但是,LinkedHashMapLinkedHashSet可以用于如果您需要特定顺序但还需要Map或Set的功能。

+0

如果我没有一个集合,但只是一个实现'Iterable'的类呢? –