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<>();
    
    @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标准库中的广泛应用:

  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;
    }
    
    @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
}

总结

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

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

适用场景

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

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

posted @ 2025-09-16 07:16  庞去广  阅读(19)  评论(0)    收藏  举报