回答
集合實際上在兩種語言中都積極使用迭代器。每當你瀏覽一個集合的元素時,即使你沒有在代碼中明確地看到它,也會涉及某種迭代器。我在Java中給出了例子,因爲我更熟悉它。
優選成語遍歷Java 5之前的集合 - 使用Iterator
明確:
for (Iterator i = c.iterator(); i.hasNext();) {
doSomething((Element) i.next()); // (No generics before 1.5)
}
而且,由於Java的5:
for (Element e : elements) {
doSomething(e);
}
在實際上是相同的字節碼後者結果雖然,在幕後使用Iterator
。
的的IEnumerable接口正是迭代器模式:)
的Java和C#的集合使用迭代器模式的引擎蓋下。這幾乎是可變收藏的必需品。
如果您選擇使用持久性集合(例如Functional Java庫中提供的那些集合),則不再需要迭代器模式。
爲什麼你不想迭代持久集合? – 2011-02-28 10:00:52
@彼得:你通常不會,這要歸功於更高階的函數來操作集合。即使你想迭代一個集合,你仍然可以通過遞歸和列表解構來實現。你不需要迭代器模式。 – 2011-02-28 10:03:13
在Java中,Iterator有其他用途,尤其是Iterator.remove()仍然有用。
IEnumerator<T>
是一個迭代器,IEnumerable<T>
創建它們。幾乎所有的收藏都實現了IEnumerable<T>
。
它是Linq-To-Objects的核心,它是C#3的核心特性之一。所以迭代器在現代C#中非常重要。
C#3還引入了一種特殊的語言功能,允許您使用yield return
語法輕鬆實現迭代器。
foreach
也基於迭代器。
+1提到'收益回報'是C#語言的那些奇妙而美麗的特徵之一。 – sheikhjabootie 2011-02-28 11:31:00
迭代器和集合的不同之處在於,集合本質上是持有項目,並且迭代器只是逐個檢索項目,而不是包含在其中。
例如,IDataReader是數據庫項目的迭代器,您可以擁有IEnumerable迭代器來訪問文件系統中的目錄條目以及集合的迭代器。
是的,我們仍然需要迭代器!
1)循環鏈表是O(n^2)
沒有迭代器。
for (int i = 0; i < list.size(); i++)
list.get(i).foo();
要進入元素#5,列表從head元素開始,並遵循4個鏈接。要到達下一個循環中的元素#6,它將再次從頭部開始,遵循所有相同的鏈接(加上一個)。一個迭代器可以很聰明地記住最後一個位置,給出O(n)
。快得多!
2)size()
存在問題。有時候你還不知道尺寸。一些生產者線程可能會添加元素,而另一個線程想要開始閱讀。如果它首先需要大小,(for(i=0;i<size;i++)
)它不能在生產者線程完成之前啓動。
集合可能非常大,以至於元素不能一起放入內存中。迭代器一次只能訪問一個元素,因此它只需要適應一個元素。
3)如何遍歷樹的所有元素?編寫這個代碼錯誤並不那麼簡單。幸運的是,您可以獲取樹中所有元素的迭代器,並快速遍歷它們,而不必擔心順序或任何事情。
迭代器隱藏了元素的存儲方式,只提供訪問權限,很好的抽象。
在許多情況下,對未知數量的項目進行迭代而不是在集合中收集所有項目會更有效。這裏有幾個例子說明了爲什麼迭代更有效率。在某些情況下,甚至不可能使用集合。
- 該列表基於緩慢的資源,無法一次提供所有項目。
- 正在生成該列表
- 列表(DB讀取器,文件,一些網絡的東西,計算)
- 源只允許向前遊標(如磁帶,DB光標,服務器客戶端流的東西)是極端長和不能一次保存在內存中
- 您正在使用鏈接列表,其中獲取下一個元素的效率高於獲取索引爲
i
的元素。 - 獲取源列表後,應根據該列表創建一個新結果。例如,應該過濾和轉換源列表。將結果保存在一個新列表中的時候效率不高,因爲只有一些值會被重用。
最後一個例子提到了linq或類似的方法,其中複雜的對象結構可以被有效地轉換。 此外,使用for
循環來處理所有項目而不是使用foreach
通常更爲複雜。
集合爲一組值包含不同類型的組織 - 如集合,列表數組等。
什麼迭代器封裝/代表是這些 -
- 在一種安全的方式集合中存儲的項目中的任何一個參考。
即使我有一個字符串列表,我的內部列表 實施將使用包含有再下以前的項目沿着字符串值 的對象。迭代器將隱藏這些可能已經被暴露的內部對象 。
- 通過他們要迭代的方式 -
根據表示 迭代器遍歷,他們可能是千差萬別的實際對象的類型。例如在 陣列上,您將轉到下一個索引。但是在列表中,您需要 才能訪問下一個或上一個項目參考。
常見操作,如第一個上一個和下一個項目。
像迭代特質,讓你知道使用迭代
支持運動的類型,以便而不必爲一個自定義矢量和acessing地圖的元素另一個自定義循環的附加信息和另一個用於訪問列表集合的自定義循環,我們現在可以有一個可以應用於這些類型的訪問循環。
事實上,這使基於模板的算法成爲可能,因爲他們現在只需要專注於他們對內容或集合所做的事情,而忽略傳遞給它們的集合的類型。
我會去說,迭代器模式是最簡單和基本的項目,像STL這樣的模板集合的整個概念開始。
- 1. 我們是否需要在ArrayList上使用迭代器?
- 2. 我們是否需要了解用於設計Rest API的數據庫模式?
- 3. 爲什麼我們需要scalaz.stream迭代?
- 4. 我們是否需要分區器?
- 5. 我們是否需要ezpublish_legacy?
- 6. 爲什麼我們需要設計模式
- 7. 我需要一個設計模式嗎?
- 8. 設計scala庫時,我們是否需要避免反思?
- 9. 我是否需要在for循環中聲明迭代器?
- 10. 生成器設計模式:爲什麼我們需要一個Director?
- 11. 爲什麼我們需要命令設計模式中的「接收器」類
- 12. 我們是否還需要「放置新」和「新操作員」?
- 13. 我是否還需要Microsoft.Bcl.Build in .net 4.5+
- 14. 當我們計算Gflop時,我們是否需要考慮指數計算?
- 15. 這是我需要完成的正確模式設計嗎?
- 16. 我們是否需要解決ConcurrentModificationException?
- 17. 我們是否需要更新Orbeon?
- 18. 我們是否需要取消按鈕?
- 19. 我們是否需要更改標題?
- 20. 我們是否需要關閉file_get_contents?
- 21. 我們是否需要在UIScrollView iOS 6+
- 22. 使用WinForms設計器時,我是否總是需要將DPI設置爲96?
- 23. 我們需要導入React還是隻需{Component,PropTypes}會做?
- 24. 我們還需要Richter的AsyncEnumerator嗎?
- 25. 需要說明 - 設計模式
- 26. 需要c#設計模式的建議
- 27. 工廠設計模式(需要批判)
- 28. 需要Prototype設計模式嗎?
- 29. 如果我們需要支持多個平臺,我們是否需要restclient
- 30. 我是否需要爲每種設備尺寸設計背景?
不,它創建迭代器,但它不是一個迭代器本身 – 2011-02-28 10:13:13
所以我不需要學習太多關於迭代器模式,因爲它已經爲我準備好了!對 ? – kevin 2011-03-01 01:31:50
@kevin:沒有太多要學習。這是一個簡單的模式:) – 2011-03-01 09:04:15