“嗨,阿米戈!”
“嗨,艾莉!”
“今天我想給大家講講迭代器。”
“迭代器實際上是與集合同時發明的。集合的主要目的是存儲元素,而迭代器的主要目的是一個一個地檢索這些元素。”
“搞到一套元素有什麼難的?”
“首先,一些集合中的元素,例如 Set,沒有既定的順序和/或順序不斷變化。”
“其次,一些數據結構可能以非常複雜的方式存儲對象:在不同的組、列表等中。換句話說,按順序分發所有元素將是一項非常重要的任務。”
“第三,集合往往會發生變化。假設您決定顯示集合的全部內容,但就在輸出中間,JVM 切換到另一個線程,該線程替換了集合的一半元素。因此,您得到的不是輸出,而是誰知道呢。”
“唔...”
“但是!這些正是迭代器可以解決的問題。迭代器是集合中的一個特殊對象,一方面可以訪問其所有私有數據並知道其內部結構,另一方面,實現了公共 Iterator 接口,讓每個人都知道如何使用它。 ”
“一些迭代器有一個內部數組,當創建迭代器時,集合中的所有元素都會被複製到這個數組中。這確保了對集合的任何後續更改都不會影響元素的數量或順序。”
“我認為你在使用for each時遇到過這個問題。你不能同時遍歷一個集合併從中刪除元素。這完全是因為迭代器的工作方式。”
“在添加到並發庫的新集合中,迭代器被重新設計以消除這個問題。”
“讓我提醒你迭代器是如何工作的。”
“Java 有一個特殊的 Iterator 接口。這是它的方法:”
Iterator<E> 接口的方法 | 描述 |
---|---|
boolean hasNext() |
檢查是否還有更多元素 |
E next() |
返回當前元素並移動到下一個。 |
void remove() |
移除當前元素 |
“迭代器可讓您連續獲取集合的所有元素。將迭代器視為類似於 InputStream 的東西更合乎邏輯——它擁有所有數據,但其任務是按順序輸出數據。”
“ next () 方法返回集合中的下一個元素。”
“ hasNext () 方法用於檢查是否還有更多元素。”
“而remove () 移除當前元素。”
“任何問題?”
“為什麼這些方法有這麼奇怪的名字?為什麼不是 isEmpty() 和 getNextElement()?”
“那不是更有意義嗎?”
“這會更有意義,但名稱來自 C++ 語言,其中迭代器出現得更早。”
“原來如此,我們繼續吧。”
“除了迭代器,還有一個Iterable接口,所有支持迭代器的集合都必須實現這個接口,它只有一個方法:”
Iterable<T> 接口的方法 | 描述 |
---|---|
Iterator<T>iterator() |
返回一個迭代器對象 |
“您可以在任何集合上使用此方法來獲取迭代器對像以遍歷其元素。讓我們遍歷 TreeSet 中的所有元素: ”
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext())
{
String item = iterator.next();
System.out.println(item);
}
“像這樣使用迭代器不是很方便——有太多多餘和明顯的代碼。當for-each循環出現在 Java 中時,情況變得更簡單了。”
“現在這段代碼更加緊湊和可讀:”
前 | 後 |
---|---|
|
|
“這是相同的代碼!兩種情況下都使用了迭代器。”
“只是它的使用隱藏在for-each循環中,注意右邊的代碼根本沒有紅字,完全隱藏了迭代器的使用。”
“ for-each循環可用於支持迭代器的任何對象。換句話說,您可以編寫自己的類,向其添加 iterator () 方法,並在 for-each 構造中使用其對象。 ”
“哇!當然,我並不急於編寫自己的集合和迭代器,但前景仍然很誘人。我會記下來的。”
此外,還有另一種流行的迭代器類型,它甚至有自己的接口。我說的是列表迭代器,即ListIterator。
“不管它們的實現如何,列表都會保持元素的順序,這使得通過迭代器使用它們更方便一些。”
“這是ListIterator <E> 接口的方法:”
方法 | 描述 |
---|---|
boolean hasNext() |
檢查前面是否還有更多元素。 |
E next() |
返回下一個元素。 |
int nextIndex() |
返回下一個元素的索引 |
void set(E e) |
改變當前元素的值 |
boolean hasPrevious() |
檢查後面是否有任何元素。 |
E previous() |
返回前一個元素 |
int previousIndex() |
返回前一個元素的索引 |
void remove() |
移除當前元素 |
void add(E e) |
將一個元素添加到列表的末尾。 |
“換句話說,在這裡我們可以向前和向後移動。還有一些其他的小特徵。”
“嗯,那是個有趣的東西。它用在什麼地方?”
“假設你想在鍊錶上來回移動。get 操作會相當慢,但 next() 操作會非常快。”
“嗯,你說服了我,我會記住的。”
“謝謝,艾莉!”
GO TO FULL VERSION