设计模式第16讲——迭代器模式(Iterator)-程序员宅基地

技术标签: 面试  java  迭代器模式  设计模式  

一、什么是迭代器模式

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

二、角色组成

  • 抽象迭代器(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——学生实体类

首先我们定义一个学生类,用来表示学生信息。

/**
 * @author Created by njy on 2023/6/25
 * 学生实体类
 */
@Data
public class Student {
    private String name;
    private Integer age;
    public Student(String name,Integer age){
        this.age=age;
        this.name=name;
    }
}

5.2 StudentIterator——抽象迭代器(Iterator)

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

import java.util.Iterator;
/**
 * @author Created by njy on 2023/6/25
 * 抽象迭代器(Iterator):学生迭代器
 * 实现Iterator接口
 * 负责定义访问和遍历元素的接口,例如提供hasNext()和next()方法。
 */
public interface StudentIterator extends Iterator<Student> {
}

5.3 StudentListIterator——具体迭代器(Concrete iterator)

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

/**
 * @author Created by njy on 2023/6/25
 * 具体迭代器(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;
    }
}

5.4 StudentAggregate——抽象聚合器(Aggregate)

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

/**
 * @author Created by njy on 2023/6/25
 * 抽象聚合器(Aggregate):学生聚合器
 * 提供创建迭代器的接口,例如可以定义一个iterator()方法。
 */
public interface StudentAggregate {
    //用于创建具体的迭代器对象
    StudentIterator iterator();
    void add(Student student);
}

5.5 ClassList——具体聚合器(Concrete Aggregate)

实现抽象聚合器定义的接口,负责创建具体的迭代器对象。

/**
 * @author Created by njy on 2023/6/25
 * 具体聚合器(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);
    }
}

5.6 testIterator

/**
 * @author Created by njy on 2023/6/25
 * 迭代器模式测试类
 */
@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());
        }
    }

}

六、总结

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

END:更多设计模式的介绍,推荐移步至 23种设计模式学习导航(Java完整版) 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45433817/article/details/131382881

智能推荐

(赠源码)Python+django+Mysql公交线路查询系统85021-计算机毕业设计_python查实时公交情况查询-程序员宅基地

文章浏览阅读335次,点赞4次,收藏2次。公交线路查询系统的主要使用者分为管理员、乘客用户,实现功能包括后台首页、轮播图、公告管理、资源管理(新闻列表、新闻分类列表)、交流管理(论坛列表、论坛分类列表)、系统用户(管理员、乘客用户)、模块管理(线路信息、异常通知、投诉建议)等功能。本系统的使用可以实现公交线路查询的信息化,可以方便用户查看公交路线信息等,可以大大提高管理效率。_python查实时公交情况查询

Datax DB2插件开发_datax 接入db2-程序员宅基地

文章浏览阅读1.4k次。对于datax来说, 其实所有的关系型数据库步骤都差不多, 不同的就在于不同的数据库对于SQL的要求:例如开发流程1. 新建module2.DB2配置文件处理1. 新建module2.DB2配置文件处理Datax/db2reader/src/main/resources/{json文件}: 负责生成jar包和json模板Datax/db2reader/pom.xml: 负责maven编译,配置依赖项Datax/db2reader/src/main/assembly/package.xml: _datax 接入db2

计算机专业毕设选题,java毕设选题-程序员宅基地

文章浏览阅读44次。计算机专业毕设选题,java毕设选题

STM32CubeMX使用-程序员宅基地

文章浏览阅读1.4k次。一、新建工程首先,打开,第一次使用的朋友可以点击右侧的和检查一下软件更新并且找到对应芯片的固件库然后下载,软件和固件库都推荐是使用最新版的,这里不多介绍。完毕之后点击来创建一个新的工程。在弹出的界面中找到并选择对应芯片型号,可以在左上角的对话框中搜索,选中后点击来新建工程。_stm32cubemx

repeater里绑定dropdownlist控件各行的值-程序员宅基地

文章浏览阅读111次。//repeater绑定数据事件绑定答案dropdownlist protected void rpQuestionAnswer_ItemDataBound(object sender, RepeaterItemEventArgs e) { DropDownList ddl = e.Item.FindControl("drpRightAnswe..._repeater设置dropdownlist的值

教资科目一如何备考?_教资科目一选择题怎么复习-程序员宅基地

文章浏览阅读233次。科目一的选择题确实有点难,其实每一年的可以选择题都有点偏。给大家分享一下,科目一的一些相关备考知识!Q:都考什么内容?A:考试内容包括职业理念、教师职业道德、教育法律法规、文化素养、基本能力五大模块。各模块所占比重如下:Q:都有什么题型?A:试卷分为单选题、材料分析题和写作题三种题型,满分为150分。五个模块的内容在试卷中题型题量如下表:Q:考试难不难?A:科目一考查考生综合素质,属于规范化考试,命题严格依照考试大纲,难度非常稳定,易于把握规律,便于考生有针对性地复习。反之,如果对考情不了解,_教资科目一选择题怎么复习

随便推点

以得物商品列表数据为例,打造python爬虫_得物爬虫-程序员宅基地

文章浏览阅读6.9k次,点赞3次,收藏31次。原创来自本人的公众号:阿嚏个技术公众号文章地址:文章仅限学习交流所用,禁止商业用途,如有不适,请联系作者删除。1、爬虫思路其实就是解决爬什么,怎么爬的问题。爬什么好解决,一般都是看中一个网站的数据,采集到本地进行分析整理。接着就是针对需要爬的页面进行分析,页面分析的过程就是解决怎么爬的问题,包括页面请求的地址、请求的参数、返回的数据格式等,这些相关问题搞清楚了,就可以用程序模拟用户的请求去获取想要的数据。本文通过得物微信小程序分析入手,获取品牌商品列表来获取在得物上架的商品信息.._得物爬虫

【pycharm】【安装和管理Python包】_pycharm 自带的python包-程序员宅基地

文章浏览阅读866次,点赞20次,收藏7次。帮助您查看解释器中的Python包,并管理它们。你可以使用这个来查看PyCharm已经安装了哪些包,例如如果你选择Flask作为你的项目类型,一些包将会被安装,比如Jinja 2和Flask包。在Packages工具窗口中,您可以输入请求,PyCharm将搜索PyPi存储库并返回与您的搜索匹配的最相关的包。如果您现在检查已安装软件包的列表,请求就在那里,准备导入并在我们的脚本中使用。在这种情况下,您需要单击三个点,然后选择删除包。要安装该软件包,您可以单击安装,这将使用该软件包的最新稳定版本。_pycharm 自带的python包

IE 10以上HTML css兼容问题,前端开发中的兼容性问题-CSS篇-程序员宅基地

文章浏览阅读944次。(一)前言浏览器兼容性问题一直都让我很头疼,网上大神们给出的解决方法也是五花八门,向后或向前兼容的说法都有,所以自己整理一下,如果有不恰当的欢迎指正!(二)CSS兼容问题的原因我觉得要解决问题,就要先找出问题的根源,所以先研究通常出现的CSS兼容问题的原因有哪些……1、浏览器内核的差异浏览器的内核是分为两个部分的,一是渲染引擎,另一个是JS引擎。现在JS引擎比较独立,内核更加倾向于说渲染引擎。由于..._ie bootstrap.min.css height兼容性

跑通yolox-s官方源码(可与yolov5s做对比试验)_yolox_s.pth-程序员宅基地

文章浏览阅读3.7k次,点赞8次,收藏37次。跑通yolox-s官方源码(可与yolov5s做对比试验)_yolox_s.pth

适用于渗透测试不同阶段的工具收集整理(转载)-程序员宅基地

文章浏览阅读1.1k次。Red Teaming / Adversary Simulation Toolkit该资源清单列表涵盖了一系列,适用于渗透测试不同阶段的开源/商业工具。如果你想为此列表添加贡献,欢迎你向我发送pull requestGithub:github.com/Snowming04内容侦察武器化交货命令与控制横向运动建立立足点升级特权数据泄露杂项参考侦察主动情报收集Ey..._gophish获取cookie

centos6.8服务器配置之编译安装PHP、配置nginx-程序员宅基地

文章浏览阅读122次。php version 5.6.31、nginx version: nginx/1.10.21、下载:wget http://cn2.php.net/distributions/php-5.6.31.tar.gz2、安装组件yum install -y gcc gcc-c++ make zlib zlib-devel pcre pcre-devel libjpeg li..._centos6 安装 libiconv.so.2