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;
    }
}

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

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

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;
    }
}

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

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

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);
    }
}

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());
        }
    }
 
}

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/452670.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一道题学会如何使用哈希表

给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,2,3], …

【2024.03.12】定时执行专家 V7.2 发布 - TimingExecutor V7.2 Release

目录 ▉ 软件介绍 ▉ 新版本 V7.2 下载地址 ▉ V7.2 新功能 ▼2024-03-12 V7.2 - 更新日志 ▉ V7.x 新UI设计 ▉ 软件介绍 《定时执行专家》是一款制作精良、功能强大、毫秒精度、专业级的定时任务执行软件。软件具有 25 种【任务类型】、12 种【触发器】触发方式&#x…

Python合并两张图片 | 先叠透明度再合并 (附Demo)

目录 前言正文 前言 用在深度学习可增加噪音&#xff0c;增加数据集等 推荐阅读&#xff1a;Pytorch 图像增强 实现翻转裁剪色调等 附代码&#xff08;全&#xff09; 正文 使用Pillow库来处理图像&#xff08;以下两张图来自网络&#xff09; 图一&#xff1a; 图二&…

vscode ubuntu c++运行环境配置

官方教程地址&#xff1a;Get Started with C on Linux in Visual Studio Code&#xff08;Get Started with C on Linux in Visual Studio Code&#xff09; 1、下载安装vscode Visual Studio Code - Code Editing. Redefined&#xff08;Visual Studio Code - Code Editing…

多特征变量序列预测 -TCN 预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

[Java、Android面试]_01_多线程: 重要参数、状态、优雅停止线程等

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料&#xff0c;感兴趣的朋友可收藏关注&#xff0c; 现分享如下&#xff1a; 文章目录 1. 线程池重要参数2. 线程池状态3. 优雅停止线程4. 线…

重载和覆盖以及隐藏有什么区别?

重载和重写以及重新定义&#xff08;隐藏&#xff09;有什么区别&#xff1f; 1.重载 重载是在一个作用域内进行的&#xff0c;多定义几个参数列表(参数类型和参数个数)不同但同名方法&#xff0c;这种叫做重载。重载通常发生在一个类内。 如: class Demo {void func() { ..…

在Linux/Ubuntu/Debian中设置字体

下载字体。 下载你喜欢的字体&#xff0c;双击并安装。 之后更新字体缓存&#xff1a; fc-cache -f -v安装 GNOME 调整。 GNOME Tweaks 是一个工具&#xff0c;允许你自定义 GNOME 桌面环境的各个方面&#xff0c;包括字体。 如果你还没有安装 GNOME Tweaks&#xff1a; …

「飞桨星河社区创作者激励计划」全新上线!丰富权益,等你领取~

为了助力更多的创作者实现在飞桨星河社区的成长&#xff0c;同时鼓励创作者们积极投入&#xff0c;记录创作者们的高光时刻&#xff0c;重磅推出**「创作者成长体系」&#xff0c;同时推出「每周精选&月度榜单」**活动&#xff0c;期待你一同加入精彩纷呈的AI学习与创作之旅…

【网络原理】TCP 协议中比较重要的一些特性(二)

目录 1、TCP 状态转换 1.1、三次握手状态 1.2、四次挥手状态 2、滑动窗口 3、流量控制 1、TCP 状态转换 TCP 状态和“线程状态”是类似的概念&#xff0c;用于描述 TCP 连接过程中正在执行什么操作。 TCP 服务器和客户端都有一定的数据结构来保存连接信息&#xff0c;而…

C++day2——引用、结构体、类

思维导图&#xff1a; 2、自己封装一个矩形类(Rect)&#xff0c; 拥有私有属性&#xff1a;宽度(width)、高度(height)&#xff0c; 定义公有成员函数初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w)更改高度的函数:set_h(int h) 输出该矩形的周长和面积函…

4款支持局域网环境使用的办公软件,可免费试用

在局域网环境下&#xff0c;选择一款合适的办公软件能极大提升团队协作效率。今天就为大家推荐4款支持局域网环境使用&#xff0c;且可免费试用的办公软件&#xff0c;分别是小鱼易连、有度即时通、石墨文档和坚果云。 一、小鱼易连 小鱼易连是一款高效的视频会议软件&#xff…

考察1学生学籍系统winform .net6 sqlserver

考察1学生学籍系统winform .net6 sqlserver 下载地址: 考察1学生学籍系统winform .net6 sqlserver winform(.net6)sqlserver数据库 只有数据库的表结构需要自己建表 启动程序 登录失败 进入主界面 项目获取&#xff1a; 项目获取&#xff1a;typora: typora/img (gitee.com…

idea Springboot 组卷管理系统LayUI框架开发mysql数据库web结构java编程计算机网页

一、源码特点 springboot 组卷管理系统是一套完善的完整信息系统&#xff0c;结合mvc框架和LayUI框架完成本系统springboot spring mybatis &#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整…

无人机远程指挥控制系统技术,无人机远程指挥中心功能详解

无人机远程指挥控制系统是一种用于实现无人机远程控制和指挥的技术。它主要基于先进的通信技术和无人机控制技术&#xff0c;使得操作人员可以在远离无人机的地方对其进行实时的控制和监控。 无人机远程指挥控制系统关键部分&#xff1a; 1. 通信技术&#xff1a;这是无人机远…

2023年对我国精油品牌战略以及行业分析

环洋咨询Global Info Research的精油市场调研报告提供精油市场的基本概况&#xff0c;包括定义&#xff0c;分类&#xff0c;应用和产业链结构&#xff0c;同时还讨论发展政策和计划以及制造流程和成本结构&#xff0c;分析精油市场的发展现状与未来市场趋势&#xff0c;并从生…

<.Net>VisaulStudio2022下用VB.net实现socket与汇川PLC进行通讯案例(Eazy521)

前言 此前&#xff0c;我写过一个VB.net环境下与西门子PLC通讯案例的博文&#xff1a; VisaulStudio2022下用VB.net实现socket与西门子PLC进行通讯案例&#xff08;优化版&#xff09; 最近项目上会用到汇川PLC比较多&#xff0c;正好有个项目有上位机通讯需求&#xff0c;于是…

Linux - 多线程

1、Linux线程概念 1.1、什么是线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是 “一个进程内部的控制序列”一切进程至少都有一个执行线程&#xff1b;线程在进程内部运行&#xff0c;本质是在进程地址空间内运…

娃哈哈大广赛命题内容详解,优胜作品分享!

2024第16届全国大学生广告艺术大赛正在火热进行中&#xff0c;你参加了吗&#xff01;大广赛是中国最大的高校广告创意竞赛活动。它由教育部高等教育司指导&#xff0c;中国传媒大学、大广赛文化传播&#xff08;北京&#xff09;有限公司共同举办&#xff0c;至今已经发布了多…

1679.K和数对的最大数目

题目&#xff1a;给你一个整数数组nums和一个整数k。 每一步操作中&#xff0c;你需要从数组中选出和为 k 的两个整数&#xff0c;并将他们移出数组。 返回你可以对数组执行的最大操作数。 解题思路&#xff1a;排序&#xff0b;双指针 class Solution{public int maxOperat…