1. 迭代器產生的背景
你已經很熟悉了HashSet
。如果你真的研究過它,而不僅僅是閱讀一節課,那麼你應該問這個問題:
如何在屏幕上顯示所有 HashSet 元素的列表?畢竟接口是沒有get()
和set()
方法的!
並且HashSet
在這個限制中並不孤單。除了HashSet
,還有許多其他集合不允許通過索引檢索元素,因為元素沒有定義的順序。
多年來,程序員發明了許多複雜的數據結構,例如圖和樹。或列表列表。
當添加新元素或刪除現有元素時,許多容器會更改其元素的順序。例如,列表以特定順序存儲元素,當添加新元素時,它幾乎總是插入到列表的中間。
我們還會遇到這樣的情況,即有一個容器存儲元素但沒有以任何固定順序存儲。
現在假設我們要將此類集合中的所有元素複製到數組或列表中。我們需要獲取所有元素。我們不關心迭代元素的順序——重要的是不要多次迭代相同的元素。我們該怎麼做?
2.集合的迭代器
迭代器被提議作為上述問題的解決方案。
迭代器是與集合關聯的特殊對象,它有助於遍歷集合中的所有元素而不重複任何元素。
您可以使用以下代碼獲取任何集合的迭代器:
Iterator<Type> it = name.iterator();
其中name
是集合變量的名稱,Type
是集合元素的類型,iterator()
是集合的方法之一,it
是迭代器變量的名稱。
迭代器對像有 3 個方法:
方法 | 描述 |
---|---|
|
返回集合中的下一個元素 |
|
檢查是否還有未遍歷的元素 |
|
移除集合的當前元素 |
這些方法有點類似於 Scanner 類的nextInt)
和hasNextInt()
方法。
該next()
方法返回我們從中獲得迭代器的集合的下一個元素。
該hasNext()
方法檢查集合是否有迭代器尚未返回的其他元素。
以下是顯示 a 的所有元素的方法HashSet
:
代碼 | 筆記 |
---|---|
|
創建一個HashSet 存儲String 元素的對象。我們將各種語言的問候語添加到 set 變量中。獲取集合的迭代器對象 set 。只要還有元素 獲取下一個元素 將元素顯示在屏幕上 |
3.For-each
循環
迭代器的主要缺點是你的代碼變得比使用for
循環更麻煩。
for
為了進行比較,讓我們使用循環並使用迭代器來顯示列表:
迭代器 | for循環 |
---|---|
|
|
是的,使用循環遍歷 an 的元素要好得多ArrayList
——一切都變得更短了。
但是 Java 的創造者再次決定給我們灌些糖。對我們來說幸運的是,它是語法糖。
他們為 Java 提供了一種新的循環,並稱之為循環for-each
。這是它的一般外觀:
for(Type name:collection)
其中collection
是集合變量的名稱,Type
是集合中元素的類型,name
是在循環的每次迭代中從集合中獲取下一個值的變量的名稱。
這種循環使用隱式迭代器遍歷集合的所有元素。這是它的實際工作方式:
For-each 循環 | 編譯器看到的:使用迭代器循環 |
---|---|
|
|
當編譯器for-each
在您的代碼中遇到循環時,它只是用右邊的代碼替換它:它添加一個調用以獲取迭代器以及任何其他缺少的方法調用。
程序員喜歡for-each
循環,並且在需要遍歷集合的所有元素時幾乎總是使用它。
ArrayList
即使使用循環遍歷列表for-each
看起來也更短:
For-each 循環 | for循環 |
---|---|
|
|
for-each
4. 刪除循環中的元素
循環for-each
有一個缺點:它不能正確地刪除元素。如果你這樣寫代碼,你會得到一個錯誤。
代碼 | 筆記 |
---|---|
|
刪除操作會產生錯誤! |
這是一個非常好的和易於理解的代碼,但它不會工作。
在使用迭代器遍歷集合時,您不能更改它。
有三種方法可以繞過此限制。
1.使用不同類型的循環
When traversing an ArrayList collection
,您可以使用帶有計數器變量的普通循環i
。
代碼 |
---|
|
但是,此選項不適用於HashSet
和HashMap
集合
2.使用顯式迭代器
您可以顯式使用迭代器並調用它的remove()
方法。
有效的版本 | 不起作用的版本 |
---|---|
|
|
請注意,我們remove()
在迭代器對像上調用該方法!迭代器知道該項目已被刪除並且可以正確處理這種情況。
3.使用集合的副本
您還可以創建集合的副本,然後在循環中使用副本for-each
並從原始集合中刪除元素。
代碼 | 筆記 |
---|---|
|
創建集合的副本非常簡單 循環使用迭代器來創建集合的副本。 元素已從 list 集合中移除。 |
集合被複製得相當快,因為元素本身沒有被複製。相反,新集合存儲對舊集合中已存在的元素的引用。
GO TO FULL VERSION