迭代器模式是一种行为型模式。迭代器模式允许对一组对象元素的遍历以完成功能实现。
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);
}
}
}
结果:
迭代器模式的注意事项:
- 提供了一种方法来顺序访问一个容器中对象的元素,而无需了解其内部表示方法。
- 该模式的核心思想是将访问和遍历容器对象的功能交给一个容器对象外部的迭代器对象
- 迭代器对象是负责跟踪当前元素,即它知道遍历过的元素
- 外部迭代器:也叫主动迭代器,客户端控制的迭代器。客户端使用外部迭代器必须由迭代器获取事先准确的下一个元素来完成遍历和请求。这样做会更加灵活,例如在对两个集合对象作比较的时候
- 内部迭代器:也叫被动迭代器,迭代器自己控制迭代。客户端调用内部迭代器来实现某项操作时,迭代器会对聚合对象中每一个元素执行操作,这样做便于实现,因为其迭代逻辑由其自身实现。
迭代器模式的应用场景:
- 需要访问一个聚合对象的内容,而无需了解其内部的表示。
- 支持对聚合对象的多种遍历方式
- 为遍历不同的聚合结构提供统一的接口。