0129_迭代器模式(Iterator)
迭代器模式(Iterator)
意图
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
UML 图

优点
- 简化访问接口:提供统一的遍历接口,简化客户端代码
- 封装内部结构:隐藏聚合对象的内部表示,提高安全性
- 支持多种遍历:可以在同一聚合上实现多种遍历方式
- 开闭原则:增加新的聚合类和迭代器类都很方便,无需修改现有代码
- 并行遍历:支持对同一聚合同时进行多个遍历
缺点
- 增加系统复杂度:需要定义额外的迭代器类,增加类的数量
- 性能开销:对于简单的聚合,使用迭代器可能比直接遍历效率低
- 可能破坏封装:某些迭代器实现可能需要访问聚合的内部细节
- 使用限制:某些语言(如Java)的迭代器是单向的,不能回退或重置
- 并发问题:在遍历过程中修改聚合可能导致并发异常
代码示例
以人类社交网络中的朋友关系为例:
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<>();
@Override
public 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);
}
}
@Override
public void addFriend(Person person) {
friends.add(person);
// 按兴趣分类
for (String interest : person.getInterests()) {
friendsByCategory.computeIfAbsent(interest, k -> new ArrayList<>()).add(person);
}
}
@Override
public 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;
}
@Override
public boolean hasNext() {
return position < friends.size();
}
@Override
public Person next() {
if (!hasNext()) {
throw new NoSuchElementException("没有更多朋友了");
}
return friends.get(position++);
}
@Override
public 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;
}
@Override
public boolean hasNext() {
return position < closeFriends.size();
}
@Override
public Person next() {
return closeFriends.get(position++);
}
@Override
public 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;
}
@Override
public boolean hasNext() {
return position < recentFriends.size();
}
@Override
public Person next() {
return recentFriends.get(position++);
}
@Override
public 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();
}
@Override
public boolean hasNext() {
while (!currentCategoryIterator.hasNext() && categoryIterator.hasNext()) {
Map.Entry<String, List<Person>> entry = categoryIterator.next();
currentCategoryIterator = entry.getValue().iterator();
}
return currentCategoryIterator.hasNext();
}
@Override
public Person next() {
if (!hasNext()) {
throw new NoSuchElementException("没有更多朋友了");
}
return currentCategoryIterator.next();
}
@Override
public void reset() {
categoryIterator = friendsByCategory.entrySet().iterator();
currentCategoryIterator = Collections.emptyIterator();
}
}
5. 人类实体类 (Person Entity)
// 人类实体
public class Person {
private String name;
private int closeness; // 亲密程度 1-10
private 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); }
@Override
public 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标准库中的广泛应用:
- 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);
}
- 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());
}
- 增强for循环(语法糖)
// 增强for循环底层使用迭代器
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) { // 编译后使用iterator()
System.out.println(name);
}
- 自定义迭代器实现
// 实现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;
}
@Override
public Iterator<Integer> iterator() {
return new RangeIterator();
}
private class RangeIterator implements Iterator<Integer> {
private int current = start;
@Override
public boolean hasNext() {
return current <= end;
}
@Override
public 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
}
总结
迭代器模式通过提供统一的遍历接口,使得客户端代码能够以一致的方式访问各种聚合对象的元素,而无需关心其内部结构。在人类社交网络的例子中,我们可以看到如何为不同类型的朋友关系(亲密朋友、最近朋友、按兴趣分类等)提供不同的遍历方式。
模式核心思想:将遍历逻辑从聚合对象中分离出来,封装到专门的迭代器对象中,实现遍历与聚合的分离,提高系统的灵活性和可维护性。
适用场景:
- 需要为聚合对象提供多种遍历方式时
- 需要统一遍历接口,屏蔽不同聚合的内部差异时
- 需要支持对同一聚合的并行遍历时
通过迭代器模式,我们能够以更加灵活和可控的方式处理集合元素的遍历,特别是在复杂的社交网络或数据集合处理场景中。

浙公网安备 33010602011771号