Skip to content

迭代器模式

什么是迭代器模式?

迭代器模式 是一种 行为型设计模式(Behavioral Design Pattern),它提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。迭代器模式将遍历元素的责任从聚合对象转移到迭代器对象上,简化了聚合类,并使得可以用不同的方式遍历一个聚合对象。

现代高级编程语言(如 Java、C#、Python、JavaScript 等)已经将迭代器模式的核心功能 直接集成到语言语法或标准库中,开发者无需手动实现迭代器接口。

应用场景

  • 需要统一遍历不同结构的聚合对象
  • 需要支持多种遍历方式(正序、逆序、过滤等)
  • 需要隐藏聚合对象的内部结构
  • 需要为聚合对象提供统一的访问接口

优缺点

优点

  • 单一职责原则:将遍历逻辑与业务逻辑分离
  • 开闭原则:可以新增迭代器而不修改聚合类
  • 可以并行遍历同一聚合对象
  • 可以暂停遍历并在之后继续

缺点

  • 对于简单集合可能过度设计
  • 迭代器可能比直接遍历效率低

模式结构(角色组成)

角色说明
Iterator(迭代器接口)定义访问和遍历元素的接口,如 hasNext()next() 等方法。
ConcreteIterator(具体迭代器)实现迭代器接口,跟踪聚合对象中的当前位置。
Aggregate(聚合对象)定义创建迭代器对象,如 createIterator() 方法。
ConcreteAggregate(具体聚合)实现聚合接口,创建与之对应的具体迭代器。

代码示例

java

public interface Iterator<T> {
    /**
     * 是否存在下一个元素
     *
     * @return
     */
    boolean hasNext();

    /**
     * 获取下一个元素
     *
     * @return
     */
    T next();

    /**
     * 重置迭代器
     */
    void reset();

    /**
     * 获取当前元素
     *
     * @return
     */
    T currentItem();

    /**
     * 回滚到上一个元素
     */
    void rollback();

    /**
     * 跳过当前元素
     */
    void skip();
}
java
    public class TodoItemIterator implements Iterator<TodoItem> {
    private TodoItem[] items; // 待办事项数组
    private int position; // 当前迭代位置

    /**
     * 构造函数
     *
     * @param items 待办事项数组
     */
    public TodoItemIterator(TodoItem[] items) {
        this.items = items;
        this.position = 0;
    }

    /**
     * 是否存在下一个元素
     *
     * @return
     */
    @Override
    public boolean hasNext() {
        return position < items.length;
    }

    /**
     * 获取下一个元素
     *
     * @return
     */
    @Override
    public TodoItem next() {
        if(!hasNext()) {
            throw new IndexOutOfBoundsException("No more items.");
        }
        return items[position++];
    }

    /**
     * 重置迭代器
     */
    @Override
    public void reset() {
        position = 0;
    }

    /**
     * 获取当前元素
     *
     * @return
     */
    @Override
    public TodoItem currentItem() {
        return items[position];
    }

    /**
     * 回滚到上一个元素
     */
    @Override
    public void rollback() {
        if (position > 0) {
            position--;
        }
    }

    /**
     * 跳过当前元素
     */
    @Override
    public void skip() {
        if (position < items.length) {
            position++;
        }
    }
}
java
    public abstract class Aggregate<T> {
    protected T[] items;
    protected int size;

    public Aggregate(int capacity) {
        this.size = 0;
        this.items = initItems(capacity);
    }

    protected abstract T[] initItems(int capacity);


    public void addItem(T item) {
        if (size < items.length) {
            items[size++] = item;
        } else {
           throw new ArrayIndexOutOfBoundsException("集合已满,无法添加新项。");
        }
    }

    protected T[] getItems() {
        return this.items;
    }

    public abstract Iterator<T> createIterator();
}
java
    public class TodoList extends Aggregate<TodoItem> {


    public TodoList(int capacity) {
        super(capacity);
    }

    @Override
    protected TodoItem[] initItems(int capacity) {
        return new TodoItem[capacity];
    }

    @Override
    public Iterator<TodoItem> createIterator() {
        return new TodoItemIterator(this.getItems());
    }
}
java
@Slf4j
public class Main {
    public static void main(String[] args) {
        // 创建待办事项
        TodoList todoList = new TodoList(10);
        todoList.addItem(new TodoItem("学习新技能", "学习Python编程", false));
        todoList.addItem(new TodoItem("去超市", "购买生活用品", false));
        todoList.addItem(new TodoItem("阅读书籍", "阅读《设计模式》", false));
        todoList.addItem(new TodoItem("锻炼身体", "去健身房锻炼", false));
        todoList.addItem(new TodoItem("学习编程", "完成Java课程", false));
        todoList.addItem(new TodoItem("参加会议", "项目进展汇报", false));
        todoList.addItem(new TodoItem("整理房间", "清理杂物", false));
        todoList.addItem(new TodoItem("写博客", "分享编程经验", false));
        todoList.addItem(new TodoItem("准备旅行", "规划下个月的旅行", false));
        todoList.addItem(new TodoItem("看电影", "观看最新上映的电影", false));

        Iterator<TodoItem> iterator = todoList.createIterator();

        // 迭代并打印待办事项
        while (iterator.hasNext()) {
            TodoItem currentItem = iterator.currentItem();
            log.info("标题: {}", currentItem.getTitle());
            log.info("描述: {}", currentItem.getDescription());
            log.info("是否完成: {}", currentItem.isCompleted());
            log.info("--------------------");
            TodoItem next = iterator.next();
            if(next.getTitle().equals("整理房间")) {
                // 如果当前任务是“学习编程”,则跳过
                iterator.skip();
            }
        }
    }
}
最近更新