【浅谈设计模式】(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. 当你希望分离遍历算法和集合对象时,可以使用迭代器模式。
相关推荐
fs哆哆17 分钟前
在VB.net中一维数组,与VBA有什么区别
java·开发语言·数据结构·算法·.net
蝎子莱莱爱打怪18 分钟前
Hadoop3.3.5、Hbase2.6.1 集群搭建&Phoenix使用记录
大数据·后端·hbase
johnZhangqi22 分钟前
深圳大学-计算机信息管理课程实验 C++ 自考模拟题
java·开发语言·c++
David爱编程34 分钟前
并发编程三大特性全解析:原子性、可见性、有序性,一文讲透!
java·后端
Sally璐璐36 分钟前
Go语言变量声明与初始化详解
java·开发语言·golang
我希望的一路生花1 小时前
Nik Collection 6.2全新版Nik降噪锐化调色PS/LR插件
人工智能·计算机视觉·设计模式·stable diffusion·aigc
你的人类朋友1 小时前
git常见操作整理(持续更新)
前端·git·后端
你的人类朋友2 小时前
git中的Fast-Forward是什么?
前端·git·后端
C4程序员2 小时前
北京JAVA基础面试30天打卡14
java·开发语言·面试
黑客影儿2 小时前
Go特有的安全漏洞及渗透测试利用方法(通俗易懂)
开发语言·后端·安全·web安全·网络安全·golang·系统安全