迭代器模式是一種行爲型模式。迭代器模式允許對一組對象元素的遍歷以完成功能實現。
UML圖:
角色說明:
Container:抽象容器:用於定義聚合關係的接口。
ConcreteContainer:具體容器:一個聚合關係的實現。
Iterator:迭代器:它會實現一個用於定義迭代器的抽象迭代器接口。
ConcreteIterator:具體迭代器:迭代器的實現。
迭代器模式的創建步驟:
- 向容器類添加一個creteIterator()方法,並賦予迭代器數據訪問權。
- 設計一個迭代器用於對容器內封裝數據的遍歷
- 客戶端請求聚合對象創建一個迭代器對象
- 客戶端使用first(),next()等方法訪問聚合類中的元素。
代碼實操:
爲一個類編寫迭代器時,很常見的一種方式是將迭代器類作爲這個類的內部類,這便於實現遍歷。我們有一個Item類,它表示菜單上的條目,每個條目都會有一個價格和名字:
public class Item {
String itemName;
float itemPrice;
public Item(String itemName, float itemPrice) {
this.itemName = itemName;
this.itemPrice = itemPrice;
}
@Override
public String toString() {
return "Item{" +
"itemName='" + itemName + '\'' +
", itemPrice=" + itemPrice +
'}';
}
}
下面是Menu類。包含了一個Item類型的條目列表。通過addItem()方法能增加條目。CreateIterator()方法會返回一個條目的迭代器。MenuIterator類是一個Menu的內部類。用於實現針對條目對象的迭代器接口。
public class Menu {
List<Item> menuItems;
public Menu(){
menuItems = new ArrayList<Item>();
}
public void addItem(Item item){
menuItems.add(item);
}
public Iterator<Item> CreateIterator(){
return new MenuIterator();
}
class MenuIterator implements Iterator<Item>{
int currentIndex = 0;
@Override
public boolean hasNext() {
if (currentIndex>=menuItems.size()){
return false;
}else {
return true;
}
}
public Item first(){
return menuItems.get(0);
}
@Override
public Item next() {
return menuItems.get(currentIndex++);
}
@Override
public void remove() {
menuItems.remove(--currentIndex);
}
}
}
IteratorTest:
public class IteratorTest {
public static void main(String[] args) {
Item i1 = new Item("Item1",10f);
Item i2 = new Item("Item2",20f);
Item i3 = new Item("Item3",30f);
Menu menu = new Menu();
menu.addItem(i1);
menu.addItem(i2);
menu.addItem(i3);
System.out.println("展示菜單...");
Iterator<Item> iterator = menu.CreateIterator();
while (iterator.hasNext()){
Item item = iterator.next();
System.out.println(item);
}
System.out.println("移除最後一條...");
iterator.remove();
System.out.println("展示菜單...");
iterator = menu.CreateIterator();
while (iterator.hasNext()){
Item item = iterator.next();
System.out.println(item);
}
}
}
結果:
迭代器模式的注意事項:
- 提供了一種方法來順序訪問一個容器中對象的元素,而無需瞭解其內部表示方法。
- 該模式的核心思想是將訪問和遍歷容器對象的功能交給一個容器對象外部的迭代器對象
- 迭代器對象是負責跟蹤當前元素,即它知道遍歷過的元素
- 外部迭代器:也叫主動迭代器,客戶端控制的迭代器。客戶端使用外部迭代器必須由迭代器獲取事先準確的下一個元素來完成遍歷和請求。這樣做會更加靈活,例如在對兩個集合對象作比較的時候
- 內部迭代器:也叫被動迭代器,迭代器自己控制迭代。客戶端調用內部迭代器來實現某項操作時,迭代器會對聚合對象中每一個元素執行操作,這樣做便於實現,因爲其迭代邏輯由其自身實現。
迭代器模式的應用場景:
- 需要訪問一個聚合對象的內容,而無需瞭解其內部的表示。
- 支持對聚合對象的多種遍歷方式
- 爲遍歷不同的聚合結構提供統一的接口。