Java迭代器指南
1.簡介
迭代器是我們遍歷集合的多種方式之一,並且每種選擇都有其優缺點。
它最初是在Java 1.2中引入的,以代替Enumerations和:
- 引入了改進的方法名稱
- 使得可以從我們正在迭代的集合中刪除元素
- 不保證迭代順序
在本教程中,我們將回顧簡單的Iterator界面,以了解如何使用其不同方法。
我們還將檢查更強大的ListIterator擴展,它添加了一些有趣的功能。
2.迭代器接口
首先,我們需要從Collection獲取一個Iterator ;這是通過調用iterator()方法完成的。
為簡單起見,我們將從列表中獲取Iterator實例:
List<String> items = ...
Iterator<String> iter = items.iterator();
Iterator接口具有三種核心方法:
2.1。 hasNext()
hasNext()方法可用於檢查是否還有至少一個要迭代的元素。
它被設計為在while循環中用作條件:
while (iter.hasNext()) {
// ...
}
2.2。下一個()
next()方法可用於跳過下一個元素並獲取它:
String next = iter.next();
在嘗試調用next()之前,最好使用hasNext () 。
集合的**迭代器不保證以任何特定順序進行迭代,除非特定的實現提供了迭代。
2.3。去掉()
最後,如果要從集合中刪除當前元素,則可以使用remove:
iter.remove();
這是在迭代集合時刪除元素的安全方法,而沒有ConcurrentModificationException的風險。
2.4。完整迭代器示例
現在,我們可以將它們全部結合起來,看看如何將這三種方法一起用於集合過濾:
while (iter.hasNext()) {
String next = iter.next();
System.out.println(next);
if( "TWO".equals(next)) {
iter.remove();
}
}
這就是我們通常使用Iterator的方式,我們會提前檢查是否還有另一個元素,我們會檢索它,然後對它執行一些操作。
2.5。使用Lambda表達式進行迭代
正如我們在前面的示例中看到的那樣,當我們只想遍歷所有元素並對它們做某事時,使用Iterator非常冗長。
從Java 8開始,我們有了forEachRemaining方法,該方法允許使用lambda處理剩餘的元素:
iter.forEachRemaining(System.out::println);
3. ListIterator接口
ListIterator是擴展,添加了用於迭代列表的新功能:
ListIterator<String> listIterator = items.listIterator(items.size());
注意我們如何提供一個起始位置,在這種情況下,該位置是列表的末尾。
3.1。 hasPrevious()和previous()
ListIterator可用於向後遍歷,因此提供了hasNext()和next()的等效項:
while(listIterator.hasPrevious()) {
String previous = listIterator.previous();
}
3.2。 nextIndex()和previousIndex()
此外,我們可以遍歷索引而不是實際元素:
String nextWithIndex = items.get(listIterator.nextIndex());
String previousWithIndex = items.get(listIterator.previousIndex());
如果我們需要知道當前正在修改的對象的索引,或者想要保留已刪除元素的記錄,這可能會非常有用。
3.3。加()
顧名思義, add方法使我們能夠在next()返回的項目之前和previous()返回的項目之後添加元素**:**
listIterator.add("FOUR");
3.4。組()
值得一提的最後一個方法是set(),它使我們可以替換調用next()或previous()時返回的元素:
String next = listIterator.next();
if( "ONE".equals(next)) {
listIterator.set("SWAPPED");
}
重要的是要注意,只有在沒有事先調用add()或remove()的情況下,才能執行此操作。
3.5。完整的ListIterator示例
現在,我們可以將它們全部結合起來以構成一個完整的示例:
ListIterator<String> listIterator = items.listIterator();
while(listIterator.hasNext()) {
String nextWithIndex = items.get(listIterator.nextIndex());
String next = listIterator.next();
if("REPLACE ME".equals(next)) {
listIterator.set("REPLACED");
}
}
listIterator.add("NEW");
while(listIterator.hasPrevious()) {
String previousWithIndex
= items.get(listIterator.previousIndex());
String previous = listIterator.previous();
System.out.println(previous);
}
在此示例中,我們首先從List中獲取ListIterator ,然後可以通過索引(這不會增加迭代器的內部當前元素)或通過調用next獲得下一個元素。
然後我們可以用set替換一個特定的項目,並用add插入一個新的項目。
到達迭代結束後,我們可以向後修改其他元素,也可以簡單地從下至上打印它們。
4。結論
Iterator接口允許我們在遍歷集合時修改其集合,而使用簡單的for / while語句則更加困難。反過來,這為我們提供了一種很好的模式,我們可以在許多方法中使用它們,只需要處理集合,同時保持良好的內聚性和低耦合度。
最後,與往常一樣,完整的源代碼可以 在GitHub上獲得。