【浅谈设计模式】(20):迭代器模式|简单入门

前言

龙年开工大吉!

迭代器模式,之前在责任链模式中出现过,结合责任链模式完成动态的模块加载。

迭代,就是遍历集合对象,其实也就是for循环,正常我们也很少使用迭代器模式,因为框架都帮我们封装好了。

那迭代器模式、与 for 循环遍历、foreach 遍历有何区别呢?

今天我们就来浅学迭代器模式。

一、概念

1.1 概念

来看相关概念。

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

回到前面的问题,遍历集合对象的三种方式:

For 循环相对 Iterator 代码更加简洁,一般情况下我们用的也最多,而foreach 底层的实现就是迭代器模式。

那为什么还要用迭代器来遍历容器呢?

原因有如下几点:

  • 1、对于线性结构的遍历,for循环完全足够了,但是在图、树的复杂遍历下,有深度优先、广度优先、前序、后序等多种遍历算法,这些遍历算法不能由我们自己来实现,也不能放到容器中不然会导致代码复杂性;解决的方式就是将遍历操作拆分到迭代器类中,例如对图的遍历,分别创建深度迭代器、广度迭代器两个迭代类;

  • 2、新增一种遍历算法,我们创建一个迭代器类,实现开闭原则。

迭代器模式的使用就是遍历和解耦容器代码。

1.2 结构

迭代器模式主要有如下四个角色:

  • Iterator(抽象迭代器):定义访问和遍历容器元素的接口,通常有 hasNext、next 等方法;

  • Concretelterator(具体迭代器):实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历;

  • Aggregate(抽象聚合):定义新增、修改、删除聚合元素以及创建迭代器对象的接口;

  • ConcreteAggregate(具体聚合):实现抽象聚合,返回一个具体的迭代器实例。

我们可以来分析下聚合和迭代器的概念。

  • 迭代器:

    • 就是控制方,可以控制切换聚合元素的控制器。
    • 将遍历数据的行为从聚合对象中分离出来,封装到迭代器对象中
  • 聚合对象:

    • 聚合对象存储具体元素对象

1.3 优缺点

优点

  • 支持多种遍历方式,只需要实现不同的迭代器,即可实现聚合对象的遍历算法;
  • 降低了聚合对象和迭代器之间的耦合度,使得聚合对象的内部结构可以随意变化而不影响遍历操作。
  • 引入抽象层,符合开闭原则

缺点

  • 新增类的个数,提高系统复杂度

  • 在某些情况下,可能会导致性能问题,因为迭代器模式需要额外的对象来维护遍历状态,可能会增加内存消耗和运行时开销。

  • 对于简单的遍历操作,使用迭代器模式可能显得过于繁琐,不利于代码的简洁性。

二、案例

迭代器案例,就是对象的遍历。

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 创建具体的元素类
class Student {
    private String name;
    private String age;

    public Student(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}

// 创建迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}

// 创建具体的迭代器类
class StudentIterator implements Iterator {
    private List<Student> students;
    private int index;

    public StudentIterator(List<Student> students) {
        this.students = students;
        this.index = 0;
    }

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

    @Override
    public Object next() {
        Student student = students.get(index);
        index++;
        return student;
    }
}

// 创建抽象聚合类
interface Aggregate {
    Iterator createIterator();
}

// 创建具体的聚合类
class StudentCollection implements Aggregate {
    private List<Student> students;

    public StudentCollection() {
        students = new ArrayList<>();
    }

    public void addStudent(Student student) {
        students.add(student);
    }

    @Override
    public Iterator createIterator() {
        return new StudentIterator(students);
    }
}

// 主程序
public class Main {
    public static void main(String[] args) {
        Student student1 = new Student("大毛", "20");
        Student student2 = new Student("二毛", "22");

        StudentCollection studentCollection = new StudentCollection();
        studentCollection.addStudent(student1);
        studentCollection.addStudent(student2);

        Iterator iterator = studentCollection.createIterator();
        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
        }
    }
}

三、小结

迭代器模式适合以下场景:

  1. 当你希望访问一个聚合对象的内容,但又不想暴露其内部结构时,可以使用迭代器模式。
  2. 当你需要对不同类型的聚合对象进行统一的遍历操作时,可以使用迭代器模式。
  3. 当你希望提供多种遍历方式(正向遍历、逆向遍历等)时,可以使用迭代器模式。
  4. 当你希望分离遍历算法和集合对象时,可以使用迭代器模式。
相关推荐
洛豳枭薰5 分钟前
jvm运行时数据区& Java 内存模型
java·开发语言·jvm
这儿有个昵称10 分钟前
互联网大厂Java面试场景:从Spring Boot到微服务架构
java·spring boot·消息队列·微服务架构·大厂面试·数据库优化
填满你的记忆1 小时前
【从零开始——Redis 进化日志|Day5】分布式锁演进史:从 SETNX 到 Redisson 的完美蜕变
java·数据库·redis·分布式·缓存
hanqunfeng1 小时前
(四十)SpringBoot 集成 Redis
spring boot·redis·后端
lendsomething1 小时前
Spring 多数据源事务管理,JPA为例
java·数据库·spring·事务·jpa
nsjqj1 小时前
JavaEE初阶:多线程初阶(2)
java·开发语言
黎雁·泠崖1 小时前
Java面向对象:对象数组核心+综合实战
java·开发语言
Mr.LJie1 小时前
记录使用iText7合并PDF文件、PDF发票、PDF火车票
java·pdf
野生技术架构师1 小时前
2026最新最全Java 面试题大全(整理版)2000+ 面试题附答案详解
java·开发语言
小北方城市网1 小时前
SpringBoot 集成 MinIO 实战(对象存储):实现高效文件管理
java·spring boot·redis·分布式·后端·python·缓存