迭代器模式 (Iterator Pattern)

文章目录

迭代器模式 (Iterator Pattern)

迭代器模式 是一种 行为型设计模式,用于顺序访问集合对象中的元素,而无需暴露集合的内部表示。它提供了一种统一的方式来遍历不同类型的集合。


原理

  1. 核心思想
    • 将集合的遍历逻辑封装在迭代器对象中,分离集合对象的存储和迭代行为。
  2. 适用场景
    • 需要访问集合对象中的内容,而不希望暴露其内部结构。
    • 需要以不同方式遍历集合。
    • 提供一个统一接口,支持多种类型集合的迭代。
  3. 参与角色
    • Iterator(迭代器接口)
      • 定义访问和遍历元素的方法。
    • ConcreteIterator(具体迭代器)
      • 实现迭代器接口,负责具体的遍历行为。
    • Aggregate(集合接口)
      • 定义创建迭代器的接口。
    • ConcreteAggregate(具体集合)
      • 实现集合接口,并返回具体的迭代器。

优点

  1. 单一职责原则
    • 集合类负责存储数据,迭代器负责遍历,分离了职责。
  2. 开放/封闭原则
    • 可以新增不同的迭代方式,而无需修改集合类。
  3. 统一接口
    • 不同集合的遍历方式对外统一。

缺点

  1. 开销
    • 如果集合很大,创建多个迭代器对象可能会增加内存开销。
  2. 访问限制
    • 某些高级操作(如随机访问)可能不适用于简单迭代器。

示例代码

场景描述

设计一个自定义集合类 CustomCollection,并提供一个迭代器来遍历其中的元素。


1. 定义迭代器接口
java 复制代码
// 迭代器接口
public interface Iterator<T> {
    boolean hasNext();  // 是否还有下一个元素
    T next();           // 获取下一个元素
}

2. 定义集合接口
java 复制代码
// 集合接口
public interface Aggregate<T> {
    Iterator<T> createIterator();  // 创建迭代器
}

3. 实现具体集合类
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 具体集合类
public class CustomCollection<T> implements Aggregate<T> {
    private List<T> items = new ArrayList<>();

    // 添加元素
    public void add(T item) {
        items.add(item);
    }

    // 获取元素
    public T get(int index) {
        return items.get(index);
    }

    // 获取集合大小
    public int size() {
        return items.size();
    }

    // 创建迭代器
    @Override
    public Iterator<T> createIterator() {
        return new CustomIterator();
    }

    // 具体迭代器类
    private class CustomIterator implements Iterator<T> {
        private int index = 0; // 当前索引

        @Override
        public boolean hasNext() {
            return index < items.size();
        }

        @Override
        public T next() {
            return items.get(index++);
        }
    }
}

4. 客户端代码
java 复制代码
public class IteratorPatternExample {
    public static void main(String[] args) {
        // 创建集合
        CustomCollection<String> collection = new CustomCollection<>();
        collection.add("Element 1");
        collection.add("Element 2");
        collection.add("Element 3");

        // 获取迭代器
        Iterator<String> iterator = collection.createIterator();

        // 使用迭代器遍历集合
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

输出结果
text 复制代码
Element 1
Element 2
Element 3

UML 类图

复制代码
        +----------------+
        |   Aggregate    |<-----------------+
        +----------------+                  |
        | + createIterator(): Iterator<T>   |
        +----------------+                  |
                ^                           |
                |                           |
  +---------------------------+     +-------------------+
  |   CustomCollection<T>     |     |    Iterator<T>    |
  +---------------------------+     +-------------------+
  | - items : List<T>         |     | + hasNext(): bool |
  | + add(item): void         |     | + next(): T       |
  | + createIterator(): CustomIterator<T> |
  +---------------------------+     +-------------------+
                ^                           ^
                |                           |
  +---------------------------+     +-------------------+
  |   CustomIterator<T>       |     |       Client      |
  +---------------------------+     +-------------------+
  | - index : int             |     
  | + hasNext(): bool         |
  | + next(): T               |
  +---------------------------+

使用场景

  1. 集合类的封装
    • 如 Java 中的 ArrayList, HashMap 的迭代器。
  2. 多种遍历方式
    • 深度优先搜索和广度优先搜索可以使用不同的迭代器实现。
  3. 复杂对象的遍历
    • 需要以特定顺序访问复杂结构中的数据。

优化与扩展

  1. 支持多种遍历方式
    • 如反向迭代器、跳步迭代器等。
  2. 线程安全
    • 提供线程安全的迭代器(如 CopyOnWriteArrayList 的迭代器)。
  3. 懒加载
    • 对于大集合,可以使用惰性迭代器按需加载数据。

小结

  • 迭代器模式使得集合的遍历行为与集合内部结构解耦。
  • 提供了统一的访问方式,但实现迭代器可能带来一定的额外开销。
  • 在实际开发中,迭代器模式广泛应用于各种集合类的遍历操作,尤其是在框架设计中非常常见。
相关推荐
边境悍匪8 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
我的xiaodoujiao8 小时前
Django 基础知识详细图文教程 9-Django 模板引擎 2
开发语言·数据库·后端·django
菜鸟~noob2338 小时前
【太空电子战】从CCS到Meadowlands:反通信系统的二十年演进史【含matlab代码】
开发语言·matlab
quantdash_cc9 小时前
量化策略为什么需要实时行情数据?从信号产生到交易决策的时间差说起
开发语言·python·数据分析·量化交易·股票数据·quantdash
逆向编程11 小时前
QGIS地图投影(CRS坐标参照系)设置
开发语言
free-elcmacom11 小时前
发际线警告!手撕《C陷阱与缺陷》终极 BOSS:signal 函数与 typedef 魔法
c语言·开发语言·visual studio code·visual studio
程序员阿鹏11 小时前
简单介绍一下软引用
java·开发语言·jvm·数据结构·后端
haluhalu.11 小时前
初识 Protobuf:微服务跨语言通信的一份契约
java·c语言·开发语言·c++·python
孙启超11 小时前
【AI开发之Rust】第 12 课:并发模型与同步原语
开发语言·后端·rust
敲代码的瓦龙12 小时前
Jetpack?DataBinding!!!
android·java·开发语言·mysql·android-studio