当前位置: 首页 > news >正文

0129_迭代器模式(Iterator)

迭代器模式(Iterator)

意图

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

UML 图

image

优点

  1. 简化访问接口:提供统一的遍历接口,简化客户端代码
  2. 封装内部结构:隐藏聚合对象的内部表示,提高安全性
  3. 支持多种遍历:可以在同一聚合上实现多种遍历方式
  4. 开闭原则:增加新的聚合类和迭代器类都很方便,无需修改现有代码
  5. 并行遍历:支持对同一聚合同时进行多个遍历

缺点

  1. 增加系统复杂度:需要定义额外的迭代器类,增加类的数量
  2. 性能开销:对于简单的聚合,使用迭代器可能比直接遍历效率低
  3. 可能破坏封装:某些迭代器实现可能需要访问聚合的内部细节
  4. 使用限制:某些语言(如Java)的迭代器是单向的,不能回退或重置
  5. 并发问题:在遍历过程中修改聚合可能导致并发异常

代码示例

以人类社交网络中的朋友关系为例:

1. 迭代器接口 (Iterator Interface)

// 迭代器接口
public interface FriendIterator {boolean hasNext();Person next();void reset();
}

2. 聚合接口 (Aggregate Interface)

// 聚合接口
public interface SocialNetwork {FriendIterator createIterator(String type);void addFriend(Person person);void removeFriend(Person person);
}

3. 具体聚合类 (Concrete Aggregate)

// 人类社交网络
public class HumanSocialNetwork implements SocialNetwork {private List<Person> friends = new ArrayList<>();private Map<String, List<Person>> friendsByCategory = new HashMap<>();@Overridepublic FriendIterator createIterator(String type) {switch (type) {case "close":return new CloseFriendsIterator(friends);case "recent":return new RecentFriendsIterator(friends);case "byInterest":return new InterestBasedIterator(friendsByCategory);default:return new AllFriendsIterator(friends);}}@Overridepublic void addFriend(Person person) {friends.add(person);// 按兴趣分类for (String interest : person.getInterests()) {friendsByCategory.computeIfAbsent(interest, k -> new ArrayList<>()).add(person);}}@Overridepublic void removeFriend(Person person) {friends.remove(person);// 从所有分类中移除for (List<Person> categoryFriends : friendsByCategory.values()) {categoryFriends.remove(person);}}public List<Person> getFriends() {return new ArrayList<>(friends); // 返回副本保护内部数据}
}

4. 具体迭代器实现 (Concrete Iterators)

// 所有朋友迭代器
public class AllFriendsIterator implements FriendIterator {private List<Person> friends;private int position;public AllFriendsIterator(List<Person> friends) {this.friends = new ArrayList<>(friends); // 保护性拷贝this.position = 0;}@Overridepublic boolean hasNext() {return position < friends.size();}@Overridepublic Person next() {if (!hasNext()) {throw new NoSuchElementException("没有更多朋友了");}return friends.get(position++);}@Overridepublic void reset() {position = 0;}
}// 亲密朋友迭代器(基于亲密程度)
public class CloseFriendsIterator implements FriendIterator {private List<Person> closeFriends;private int position;public CloseFriendsIterator(List<Person> allFriends) {this.closeFriends = allFriends.stream().filter(friend -> friend.getCloseness() >= 8) // 亲密程度8分以上.sorted((f1, f2) -> Integer.compare(f2.getCloseness(), f1.getCloseness())).collect(Collectors.toList());this.position = 0;}@Overridepublic boolean hasNext() {return position < closeFriends.size();}@Overridepublic Person next() {return closeFriends.get(position++);}@Overridepublic void reset() {position = 0;}
}// 最近添加的朋友迭代器
public class RecentFriendsIterator implements FriendIterator {private List<Person> recentFriends;private int position;public RecentFriendsIterator(List<Person> allFriends) {this.recentFriends = allFriends.stream().sorted((f1, f2) -> f2.getAddedDate().compareTo(f1.getAddedDate())).limit(10) // 最近10个朋友.collect(Collectors.toList());this.position = 0;}@Overridepublic boolean hasNext() {return position < recentFriends.size();}@Overridepublic Person next() {return recentFriends.get(position++);}@Overridepublic void reset() {position = 0;}
}// 基于兴趣的迭代器
public class InterestBasedIterator implements FriendIterator {private Map<String, List<Person>> friendsByCategory;private Iterator<Map.Entry<String, List<Person>>> categoryIterator;private Iterator<Person> currentCategoryIterator;public InterestBasedIterator(Map<String, List<Person>> friendsByCategory) {this.friendsByCategory = new HashMap<>(friendsByCategory);this.categoryIterator = this.friendsByCategory.entrySet().iterator();this.currentCategoryIterator = Collections.emptyIterator();}@Overridepublic boolean hasNext() {while (!currentCategoryIterator.hasNext() && categoryIterator.hasNext()) {Map.Entry<String, List<Person>> entry = categoryIterator.next();currentCategoryIterator = entry.getValue().iterator();}return currentCategoryIterator.hasNext();}@Overridepublic Person next() {if (!hasNext()) {throw new NoSuchElementException("没有更多朋友了");}return currentCategoryIterator.next();}@Overridepublic void reset() {categoryIterator = friendsByCategory.entrySet().iterator();currentCategoryIterator = Collections.emptyIterator();}
}

5. 人类实体类 (Person Entity)

// 人类实体
public class Person {private String name;private int closeness; // 亲密程度 1-10private LocalDate addedDate;private Set<String> interests;public Person(String name, int closeness, Set<String> interests) {this.name = name;this.closeness = closeness;this.addedDate = LocalDate.now();this.interests = new HashSet<>(interests);}// Getter方法public String getName() { return name; }public int getCloseness() { return closeness; }public LocalDate getAddedDate() { return addedDate; }public Set<String> getInterests() { return new HashSet<>(interests); }@Overridepublic String toString() {return name + " (亲密程度: " + closeness + ", 兴趣: " + interests + ")";}
}

6. 客户端代码

public class IteratorPatternDemo {public static void main(String[] args) {System.out.println("=== 迭代器模式演示 - 人类社交网络 ===\n");// 创建社交网络SocialNetwork socialNetwork = new HumanSocialNetwork();// 添加朋友socialNetwork.addFriend(new Person("张三", 9, Set.of("音乐", "运动")));socialNetwork.addFriend(new Person("李四", 7, Set.of("读书", "旅游")));socialNetwork.addFriend(new Person("王五", 10, Set.of("运动", "美食")));socialNetwork.addFriend(new Person("赵六", 6, Set.of("电影", "游戏")));socialNetwork.addFriend(new Person("钱七", 8, Set.of("音乐", "艺术")));System.out.println("1. 遍历所有朋友:");FriendIterator allIterator = socialNetwork.createIterator("all");while (allIterator.hasNext()) {System.out.println("   👥 " + allIterator.next());}System.out.println("\n2. 遍历亲密朋友 (亲密程度≥8):");FriendIterator closeIterator = socialNetwork.createIterator("close");while (closeIterator.hasNext()) {System.out.println("   ❤️ " + closeIterator.next());}System.out.println("\n3. 按兴趣分类遍历朋友:");FriendIterator interestIterator = socialNetwork.createIterator("byInterest");while (interestIterator.hasNext()) {System.out.println("   🎯 " + interestIterator.next());}System.out.println("\n4. 重置迭代器并重新遍历:");closeIterator.reset();while (closeIterator.hasNext()) {System.out.println("   🔄 " + closeIterator.next());}// 演示多种遍历方式同时进行System.out.println("\n5. 同时进行多种遍历:");FriendIterator iterator1 = socialNetwork.createIterator("all");FriendIterator iterator2 = socialNetwork.createIterator("close");System.out.println("   所有朋友中的第一个: " + iterator1.next());System.out.println("   亲密朋友中的第一个: " + iterator2.next());System.out.println("   所有朋友中的第二个: " + iterator1.next());}
}

在Java标准库中的应用

迭代器模式在Java标准库中的广泛应用:

  1. Collection框架
// Java集合框架中的迭代器
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator(); // 创建迭代器while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);
}
  1. Map的keySet和entrySet
// Map的迭代器使用
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);// 遍历键
Iterator<String> keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {System.out.println(keyIterator.next());
}// 遍历键值对
Iterator<Map.Entry<String, Integer>> entryIterator = map.entrySet().iterator();
while (entryIterator.hasNext()) {Map.Entry<String, Integer> entry = entryIterator.next();System.out.println(entry.getKey() + ": " + entry.getValue());
}
  1. 增强for循环(语法糖)
// 增强for循环底层使用迭代器
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) { // 编译后使用iterator()System.out.println(name);
}
  1. 自定义迭代器实现
// 实现Iterable接口创建自定义迭代器
public class Range implements Iterable<Integer> {private final int start;private final int end;public Range(int start, int end) {this.start = start;this.end = end;}@Overridepublic Iterator<Integer> iterator() {return new RangeIterator();}private class RangeIterator implements Iterator<Integer> {private int current = start;@Overridepublic boolean hasNext() {return current <= end;}@Overridepublic Integer next() {if (!hasNext()) throw new NoSuchElementException();return current++;}}
}// 使用自定义迭代器
Range range = new Range(1, 5);
for (int num : range) {System.out.println(num); // 输出1,2,3,4,5
}

总结

迭代器模式通过提供统一的遍历接口,使得客户端代码能够以一致的方式访问各种聚合对象的元素,而无需关心其内部结构。在人类社交网络的例子中,我们可以看到如何为不同类型的朋友关系(亲密朋友、最近朋友、按兴趣分类等)提供不同的遍历方式。

模式核心思想:将遍历逻辑从聚合对象中分离出来,封装到专门的迭代器对象中,实现遍历与聚合的分离,提高系统的灵活性和可维护性。

适用场景

  • 需要为聚合对象提供多种遍历方式时
  • 需要统一遍历接口,屏蔽不同聚合的内部差异时
  • 需要支持对同一聚合的并行遍历时

通过迭代器模式,我们能够以更加灵活和可控的方式处理集合元素的遍历,特别是在复杂的社交网络或数据集合处理场景中。

http://www.wxhsa.cn/company.asp?id=5274

相关文章:

  • HJ7 取近似值
  • 读人形机器人13艺术领域
  • 活动报名:Voice First!Demo Day@Voice Agent Camp,9.22,上海丨超音速计划 2025
  • Windows计算器:现代C++实现的多功能计算工具
  • 使用 PySide6/PyQt6 实现系统图标的展示与交互
  • 如何让Java的线程池顺序执行任务 ?
  • Git 提交排除文件夹方法总结
  • 如何在 Ubuntu24.04 TLS 上安装 Kubernetes 集群 - Antonie
  • Jmeter的插件开发
  • Educational Codeforces Round 182 (Rated for Div. 2)
  • java第二周课前提问
  • java GC
  • Redis最佳实践——性能优化技巧之监控与告警详解
  • week1
  • EF Core 与 MySQL:迁移和关系配置详解
  • 《原子习惯》-读书笔记2
  • CF1626D 题解
  • Python 集合运算:并集、交集、差集全解析
  • 第一周数据可视化作业
  • 用 C++ + OpenCV + Tesseract 实现英文数字验证码识别
  • java 第一节课课前提问
  • 二进制解码器、选通器和分配器
  • 2025最新版 Photoshop软件免费下载安装完整教程(PS2025)超详细安装教程
  • nac一键卸载软件脚本
  • 交叉编译openharmony版本的openssh
  • 为什么不建议在 Docker 中跑 MySQL
  • CFD
  • [MCP][05]Elicitation示例
  • Warsaw主题关闭导航条
  • Python Socket网络编程(2)