迭代器模式
简介
提供一种方法顺序访问聚合对象中的各个元素,而又不暴露其内部表示。
使用场景:
Java集合框架(Iterator)
数据库结果集(ResultSet)
文件系统遍历
树形结构遍历
实现要点:
统一的遍历接口
隐藏内部结构
支持多种遍历方式
UML
代码示例
迭代器的元素,菜品菜单
public class MenuItem {
private String name;
private String description;
private boolean vegetarian;
private double price;
public MenuItem(String name, String description, boolean vegetarian, double price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public boolean isVegetarian() {
return vegetarian;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return String.format("%-20s ¥%.2f%s\n %s",
name, price,
vegetarian ? " (素)" : "",
description);
}
}迭代器接口
public interface Iterator<T> {
/**
* 是否有下一个元素
*/
boolean hasNext();
/**
* 获取下一个元素
*/
T next();
/**
* 移除当前元素(可选操作)
*/
default void remove() {
throw new UnsupportedOperationException("不支持移除操作");
}
}聚合接口,包含:迭代器的创建、添加元素。
public interface Aggregate<T> {
/**
* 创建迭代器
*/
Iterator<T> createIterator();
/**
* 添加元素
*/
void add(T item);
/**
* 获取元素数量
*/
int size();
}具体实现
//早餐菜单 - 使用ArrayList存储
public class BreakfastMenu implements Aggregate<MenuItem> {
private List<MenuItem> menuItems;
public BreakfastMenu() {
menuItems = new ArrayList<>();
// 初始化早餐菜单
add(new MenuItem("素食早餐", "吐司配水煮蛋", true, 15.00));
add(new MenuItem("传统早餐", "油条豆浆", true, 8.00));
add(new MenuItem("西式早餐", "培根煎蛋三明治", false, 25.00));
add(new MenuItem("养生粥", "小米南瓜粥", true, 12.00));
}
@Override
public void add(MenuItem item) {
menuItems.add(item);
}
@Override
public Iterator<MenuItem> createIterator() {
return new BreakfastMenuIterator();
}
@Override
public int size() {
return menuItems.size();
}
/**
* 早餐菜单迭代器 - 使用List索引遍历
*/
private class BreakfastMenuIterator implements Iterator<MenuItem> {
private int position = 0;
@Override
public boolean hasNext() {
return position < menuItems.size();
}
@Override
public MenuItem next() {
MenuItem item = menuItems.get(position);
position++;
return item;
}
}
}
//午餐菜单 - 使用数组存储
public class LunchMenu implements Aggregate<MenuItem> {
private static final int MAX_ITEMS = 6;
private MenuItem[] menuItems;
private int numberOfItems = 0;
public LunchMenu() {
menuItems = new MenuItem[MAX_ITEMS];
// 初始化午餐菜单
add(new MenuItem("宫保鸡丁", "经典川菜", false, 38.00));
add(new MenuItem("鱼香肉丝", "酸辣可口", false, 35.00));
add(new MenuItem("麻婆豆腐", "麻辣鲜香", true, 28.00));
add(new MenuItem("红烧肉", "肥而不腻", false, 45.00));
add(new MenuItem("清炒时蔬", "健康营养", true, 18.00));
}
@Override
public void add(MenuItem item) {
if (numberOfItems >= MAX_ITEMS) {
System.err.println("菜单已满,无法添加更多菜品");
} else {
menuItems[numberOfItems] = item;
numberOfItems++;
}
}
@Override
public Iterator<MenuItem> createIterator() {
return new LunchMenuIterator();
}
@Override
public int size() {
return numberOfItems;
}
/**
* 午餐菜单迭代器 - 使用数组索引遍历
*/
private class LunchMenuIterator implements Iterator<MenuItem> {
private int position = 0;
@Override
public boolean hasNext() {
return position < numberOfItems && menuItems[position] != null;
}
@Override
public MenuItem next() {
MenuItem item = menuItems[position];
position++;
return item;
}
}
}
//晚餐菜单 - 使用HashMap存储
public class DinnerMenu implements Aggregate<MenuItem> {
private Map<String, MenuItem> menuItems;
public DinnerMenu() {
menuItems = new HashMap<>();
// 初始化晚餐菜单
add(new MenuItem("龙虾套餐", "澳洲龙虾配黄油", false, 288.00));
add(new MenuItem("牛排套餐", "安格斯牛排", false, 188.00));
add(new MenuItem("海鲜大餐", "各式海鲜拼盘", false, 258.00));
add(new MenuItem("素食套餐", "精选素食", true, 88.00));
}
@Override
public void add(MenuItem item) {
menuItems.put(item.getName(), item);
}
@Override
public Iterator<MenuItem> createIterator() {
return new DinnerMenuIterator();
}
@Override
public int size() {
return menuItems.size();
}
/**
* 晚餐菜单迭代器 - 使用Map的values遍历
*/
private class DinnerMenuIterator implements Iterator<MenuItem> {
private java.util.Iterator<MenuItem> iterator;
public DinnerMenuIterator() {
iterator = menuItems.values().iterator();
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public MenuItem next() {
return iterator.next();
}
}
}迭代器使用者
public class Waitress {
private Aggregate<MenuItem> breakfastMenu;
private Aggregate<MenuItem> lunchMenu;
private Aggregate<MenuItem> dinnerMenu;
public Waitress(Aggregate<MenuItem> breakfastMenu,
Aggregate<MenuItem> lunchMenu,
Aggregate<MenuItem> dinnerMenu) {
this.breakfastMenu = breakfastMenu;
this.lunchMenu = lunchMenu;
this.dinnerMenu = dinnerMenu;
}
/**
* 打印所有菜单
*/
public void printMenu() {
System.out.println("📋 ========== 餐厅菜单 ==========\n");
System.out.println("🌅 早餐菜单:");
printMenu(breakfastMenu.createIterator());
System.out.println("\n🌞 午餐菜单:");
printMenu(lunchMenu.createIterator());
System.out.println("\n🌙 晚餐菜单:");
printMenu(dinnerMenu.createIterator());
}
/**
* 打印单个菜单
*/
private void printMenu(Iterator<MenuItem> iterator) {
while (iterator.hasNext()) {
MenuItem item = iterator.next();
System.out.println(" " + item);
}
}
/**
* 打印素食菜单
*/
public void printVegetarianMenu() {
System.out.println("\n🥬 ========== 素食菜单 ==========\n");
System.out.println("🌅 早餐:");
printVegetarianMenu(breakfastMenu.createIterator());
System.out.println("\n🌞 午餐:");
printVegetarianMenu(lunchMenu.createIterator());
System.out.println("\n🌙 晚餐:");
printVegetarianMenu(dinnerMenu.createIterator());
}
/**
* 打印素食菜单项
*/
private void printVegetarianMenu(Iterator<MenuItem> iterator) {
while (iterator.hasNext()) {
MenuItem item = iterator.next();
if (item.isVegetarian()) {
System.out.println(" " + item);
}
}
}
/**
* 检查是否有某个菜品
*/
public boolean isItemVegetarian(String name) {
Iterator<MenuItem> iterator = breakfastMenu.createIterator();
if (isItemVegetarian(iterator, name)) {
return true;
}
iterator = lunchMenu.createIterator();
if (isItemVegetarian(iterator, name)) {
return true;
}
iterator = dinnerMenu.createIterator();
return isItemVegetarian(iterator, name);
}
private boolean isItemVegetarian(Iterator<MenuItem> iterator, String name) {
while (iterator.hasNext()) {
MenuItem item = iterator.next();
if (item.getName().equals(name)) {
return item.isVegetarian();
}
}
return false;
}
}
使用方式
public class Test {
public static void main(String[] args) {
System.out.println("=== 迭代器模式 - 餐厅菜单示例 ===\n");
// 创建不同的菜单(使用不同的数据结构)
Aggregate<MenuItem> breakfastMenu = new BreakfastMenu(); // 使用ArrayList
Aggregate<MenuItem> lunchMenu = new LunchMenu(); // 使用数组
Aggregate<MenuItem> dinnerMenu = new DinnerMenu(); // 使用HashMap
System.out.println("📝 菜单信息:");
System.out.println(" 早餐菜单: 使用ArrayList存储,共" + breakfastMenu.size() + "道菜");
System.out.println(" 午餐菜单: 使用数组存储,共" + lunchMenu.size() + "道菜");
System.out.println(" 晚餐菜单: 使用HashMap存储,共" + dinnerMenu.size() + "道菜");
// 创建服务员
Waitress waitress = new Waitress(breakfastMenu, lunchMenu, dinnerMenu);
// ========== 场景1:打印所有菜单 ==========
System.out.println("\n【场景1:打印所有菜单】");
System.out.println("服务员不需要知道菜单的内部实现,统一使用迭代器遍历\n");
waitress.printMenu();
// ========== 场景2:打印素食菜单 ==========
System.out.println("\n\n【场景2:打印素食菜单】");
System.out.println("通过迭代器过滤素食菜品\n");
waitress.printVegetarianMenu();
// ========== 场景3:查询特定菜品 ==========
System.out.println("\n\n【场景3:查询特定菜品】");
String[] dishesToCheck = {"麻婆豆腐", "宫保鸡丁", "清炒时蔬", "红烧肉"};
for (String dish : dishesToCheck) {
boolean isVeg = waitress.isItemVegetarian(dish);
System.out.println(" \"" + dish + "\" 是素食? " + (isVeg ? "✅ 是" : "❌ 否"));
}
// ========== 场景4:演示迭代器的独立性 ==========
System.out.println("\n\n【场景4:演示迭代器的独立性】");
System.out.println("可以同时创建多个迭代器,互不影响\n");
Iterator<MenuItem> iterator1 = breakfastMenu.createIterator();
Iterator<MenuItem> iterator2 = breakfastMenu.createIterator();
System.out.println("迭代器1遍历早餐菜单:");
int count1 = 0;
while (iterator1.hasNext()) {
MenuItem item = iterator1.next();
count1++;
System.out.println(" " + count1 + ". " + item.getName());
}
System.out.println("\n迭代器2独立遍历早餐菜单:");
int count2 = 0;
while (iterator2.hasNext()) {
MenuItem item = iterator2.next();
count2++;
System.out.println(" " + count2 + ". " + item.getName());
}
// ========== 对比不使用迭代器 ==========
System.out.println("\n\n【对比:不使用迭代器模式】");
System.out.println("\n❌ 不使用迭代器:");
System.out.println(" - 需要知道每个菜单的内部实现(ArrayList、数组、HashMap)");
System.out.println(" - 遍历代码不统一,需要针对每种数据结构编写不同代码");
System.out.println(" - 代码耦合度高,难以维护和扩展");
System.out.println("\n✅ 使用迭代器:");
System.out.println(" - 统一的遍历接口,不需要知道内部实现");
System.out.println(" - 遍历代码统一,易于维护");
System.out.println(" - 低耦合,可以轻松添加新的菜单类型");
// ========== 总结 ==========
System.out.println("\n\n=== 迭代器模式说明 ===");
System.out.println("1. 迭代器接口: Iterator - 定义遍历方法");
System.out.println("2. 聚合接口: Aggregate - 定义创建迭代器的方法");
System.out.println("3. 具体聚合: BreakfastMenu等 - 实现具体的数据结构");
System.out.println("4. 具体迭代器: 内部类 - 实现具体的遍历逻辑");
System.out.println("5. 客户端: Waitress - 使用迭代器统一遍历");
System.out.println("\n=== 迭代器模式优势 ===");
System.out.println("✅ 统一接口: 提供统一的遍历方式");
System.out.println("✅ 封装性: 隐藏聚合对象的内部结构");
System.out.println("✅ 单一职责: 遍历逻辑与数据结构分离");
System.out.println("✅ 多种遍历: 可以为同一聚合提供多种遍历方式");
System.out.println("✅ 简化聚合接口: 聚合对象不需要提供遍历方法");
System.out.println("\n=== 迭代器模式应用场景 ===");
System.out.println("📌 集合遍历: Java集合框架的Iterator");
System.out.println("📌 树形结构: 遍历树、图等复杂结构");
System.out.println("📌 分页查询: 数据库结果集的遍历");
System.out.println("📌 文件系统: 遍历文件和目录");
System.out.println("📌 网络数据: 流式数据的遍历");
System.out.println("\n=== Java中的迭代器模式 ===");
System.out.println("🔸 java.util.Iterator: Java标准迭代器接口");
System.out.println("🔸 java.util.Iterable: 可迭代接口");
System.out.println("🔸 for-each循环: 基于迭代器实现");
System.out.println("🔸 Stream API: 增强的迭代器");
System.out.println("🔸 ResultSet: JDBC结果集迭代器");
System.out.println("\n=== 迭代器模式关键点 ===");
System.out.println("🔑 分离遍历行为: 将遍历逻辑从聚合对象中分离");
System.out.println("🔑 统一接口: 所有迭代器实现相同接口");
System.out.println("🔑 内部迭代器: 通常作为聚合对象的内部类");
System.out.println("🔑 多游标: 可以同时存在多个迭代器");
}
}Last updated
Was this helpful?