2013-09-24 49 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'的類呢? –