• 15、设计模式之迭代器模式(Iterator)


    一、什么是迭代器模式
    迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。

    二、角色组成

    抽象迭代器(Iterator):定义了遍历聚合对象所需的方法,包括hashNext()和next()方法等,用于遍历聚合对象中的元素。
    具体迭代器(Concrete
    Iterator):它是实现迭代器接口的具体实现类,负责具体的遍历逻辑。它保存了当前遍历的位置信息,并可以根据需要向前或向后遍历集合元素。
    抽象聚合器(Aggregate):
    一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
    具体聚合器(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。

    三、 优缺点

    优点:

    简化了集合类的接口,使用者可以更加简单地遍历集合对象,而不需要了解集合内部结构和实现细节。
    将集合和遍历操作解耦,使得我们可以更灵活地使用不同的迭代器来遍历同一个集合,根据需求选择不同的遍历方式。
    满足开闭原则,如果需要增加新的遍历方式,只需实现一个新的具体迭代器即可,不需要修改原先聚合对象的代码。
    缺点:

    具体迭代器实现的算法对外不可见,因此不利于调试和维护。
    对于某些小型、简单的集合对象来说,使用迭代器模式可能会显得过于复杂,增加了代码的复杂性。

    四、应用场景
    4.1 生活场景
    遍历班级名单:假设你是一名班主任,你需要遍历班级名单来点名。班级名单可以看作是一个集合,每个学生名字可以看作是集合中的一个元素。使用迭代器模式,你可以通过迭代器对象逐个访问学生的名字,而不需要了解班级名单的具体实现细节。
    遍历音乐播放列表:当我们在手机或电脑上播放音乐时,通常会创建一个播放列表。播放列表可以被视为一个集合,每首歌曲可以被视为集合中的一个元素。使用迭代器模式,我们可以通过迭代器对象逐个访问播放列表中的歌曲,进行播放、暂停或切歌等操作。
    4.2 java场景

    集合框架中的迭代器:在Java中,集合包括List、Set、Map等等,每个集合类中都提供了一个获取迭代器的方法,例如List提供的iterator()方法、Set提供的iterator()方法等等。通过获取对应的迭代器对象,可以对集合中的元素进行遍历和访问。
    JDBC中的ResultSet对象:在Java中,如果需要对数据库中的数据进行遍历和访问,可以使用JDBC操作数据库。JDBC中,查询结果集使用ResultSet对象来表示,通过使用ResultSet的next()方法,就可以像使用迭代器一样遍历和访问查询结果中的数据。
    文件读取:在Java中,我们可以使用BufferedReader类来读取文本文件。BufferedReader类提供了一个方法readLine()来逐行读取文件内容。实际上,BufferedReader在内部使用了迭代器模式来逐行读取文本文件的内容。

    五、代码实现
    下面以班级名单为例,解释一下迭代器模式。

    抽象迭代器:StudentIterator
    具体迭代器:StudentListIterator
    抽象聚合器:StudentAggregate
    具体聚合器:ClassList

    5.0 UML类图
    在这里插入图片描述

    5.1 Student——学生实体类
    首先我们定义一个学生类,用来表示学生信息。

    /**
     * 
     * 学生实体类
     */
    @Data
    public class Student {
        private String name;
        private Integer age;
        public Student(String name,Integer age){
            this.age=age;
            this.name=name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.2 StudentIterator——抽象迭代器(Iterator)
    接下来创建一个抽象迭代器(学生迭代器)并继承Iterator接口(java.util包下的Iterator)

    import java.util.Iterator;
    /**
     * 
     * 抽象迭代器(Iterator):学生迭代器
     * 实现Iterator接口
     * 负责定义访问和遍历元素的接口,例如提供hasNext()和next()方法。
     */
    public interface StudentIterator extends Iterator<Student> {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.3 StudentListIterator——具体迭代器(Concrete iterator)
    在这个具体迭代器中,实现抽象迭代器,重写hashNext()和next()方法。

    /**
     * 
     * 具体迭代器(Concrete iterator):
     * 实现抽象迭代器定义的接口,负责实现对元素的访问和遍历。
     */
    public class StudentListIterator implements StudentIterator{
        private List<Student> students;
        private int index;
     
        public StudentListIterator(List<Student> students) {
            this.students = students;
            this.index = 0;
        }
     
        //检查是否还有下一个元素
        @Override
        public boolean hasNext() {
            return (index < students.size());
        }
     
        //返回下一个元素
        @Override
        public Student next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            Student student = students.get(index);
            index++;
            return student;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5.4 StudentAggregate——抽象聚合器(Aggregate)
    定义一个抽象聚合器,并定义一个iterator()方法,用于创建具体的迭代器对象。

    /**
     * 
     * 抽象聚合器(Aggregate):学生聚合器
     * 提供创建迭代器的接口,例如可以定义一个iterator()方法。
     */
    public interface StudentAggregate {
        //用于创建具体的迭代器对象
        StudentIterator iterator();
        void add(Student student);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.5 ClassList——具体聚合器(Concrete Aggregate)
    实现抽象聚合器定义的接口,负责创建具体的迭代器对象。

    /**
     * 
     * 具体聚合器(ConcreteAggregate):班级列表
     * 实现抽象聚合器定义的接口,负责创建具体的迭代器对象,并返回该对象。
     */
    public class ClassList implements StudentAggregate{
        private List<Student> students = new ArrayList<>();
     
        //创建迭代器对象
        @Override
        public StudentIterator iterator() {
            return new StudentListIterator(students);
        }
     
        //向班级名单中添加学生信息
        @Override
        public void add(Student student) {
            students.add(student);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5.6 testIterator

    /**
     * 
     * 迭代器模式测试类
     */
    @SpringBootTest
    public class TestIterator {
        @Test
        void testIterator(){
            ClassList classList = new ClassList();
            // 添加学生信息
            classList.add(new Student("张三", 18));
            classList.add(new Student("李四", 19));
            classList.add(new Student("王五", 20));
            // 获取迭代器,遍历学生信息
            StudentIterator iterator = classList.iterator();
            while(iterator.hasNext()) {
                Student student = iterator.next();
                System.out.println("学生姓名:" + student.getName() + ",学生年龄:" + student.getAge());
            }
        }
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    六、总结
    迭代器模式提供了一种统一的方式来遍历集合对象中的元素。
    它将遍历操作封装到一个独立的迭代器对象中,使得我们可以按照特定的方式访问集合中的元素。
    迭代器模式将集合对象和遍历操作分离开来,提高了代码的灵活性和可维护性。
    使用迭代器模式可以让我们用相同的方式遍历不同类型的集合对象,而不需要了解集合的内部结构。

  • 相关阅读:
    (数据科学学习手札145)在Python中利用yarl轻松操作url
    展锐T618/T610安卓4G核心板/开发板/方案定制
    Zabbix监控指定端口
    IT项目经理必备的五种能力
    说说Spring常用的注解
    主流编程语言最好的编辑器,你的工具用对了吗?
    Vue 核心Ⅳ(内置指令和自定义指令)
    Spring @Transactional 原理解析
    企业级java笔试题,面试题第二篇
    科技的成就(三十三)
  • 原文地址:https://blog.csdn.net/weixin_45817985/article/details/136672923