「聊设计模式」之迭代器模式(Iterator)


🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


前言

  设计模式是软件开发中经验的总结,是一种被反复使用,经过验证的通用解决方案,也是软件技术人员在设计和开发中面对常见问题时的可复用的解决方案。迭代器模式是设计模式中的一种,它可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素。

摘要

  在软件开发过程中,我们经常需要遍历集合中的元素,但是如果直接使用集合提供的遍历方法,就会暴露集合底层实现的细节,迭代器模式可以解决这个问题。在本文中,我们将介绍迭代器模式的实现原理、代码示例和测试用例,希望能够帮助读者更好地理解和使用迭代器模式。

迭代器模式

概述

  迭代器模式是一种行为型设计模式,它可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素。迭代器模式将遍历集合的操作封装到一个迭代器类中,客户端只需要通过迭代器的接口就可以遍历集合中的元素。

结构

迭代器模式有以下几个角色:

  • 抽象聚合类(Aggregate),定义集合对象的接口,封装了集合底层实现的细节,提供了一个可以遍历集合中元素的抽象方法。
  • 具体聚合类(ConcreteAggregate),实现抽象聚合类中的抽象方法,返回一个具体的迭代器。
  • 抽象迭代器类(Iterator),定义遍历集合元素的接口,包括获取下一个元素、判断是否遍历完毕等方法。
  • 具体迭代器类(ConcreteIterator),实现抽象迭代器类中定义的方法,负责遍历集合中的元素。

其迭代器模式结构图如下所示:

在这里插入图片描述

迭代器模式优缺点

优点

迭代器模式的优点是:

  • 封装性好,客户端不需要知道集合内部结构,就可以遍历集合中的元素。
  • 对于不同的集合类型,我们可以定义不同的迭代器,从而实现不同的遍历方法。

缺点

迭代器模式的缺点是:

  • 迭代器模式增加了类的数量,如果需要遍历的集合比较简单,使用迭代器模式可能会增加不必要的复杂性。
  • 遍历集合时,如果有多个线程同时进行遍历操作,需要对迭代器对象进行同步操作,这会影响程序的性能。

使用场景

迭代器模式的场景包括:

  1. 需要遍历一个聚合对象(如一个列表、数组等)中的元素,但是不想暴露聚合对象的内部结构。

  2. 需要对聚合对象进行多种方式的遍历,如顺序遍历、倒序遍历等。

  3. 需要在遍历过程中实现某些操作,如筛选、过滤等。

  4. 需要在多个不同的聚合对象上进行相同的操作,而不需要关心它们的具体实现。

  5. 需要提供一种统一的遍历接口,以便客户端可以使用相同的方式处理不同的聚合对象。

例子:

  1. 遍历一个网站上的文章列表,以便按照用户的需求进行排序、搜索等操作。

  2. 遍历一个电商平台上的商品列表,以便实现商品的分类、筛选、排序等操作。

  3. 遍历一个音乐播放器中的歌曲列表,以便实现歌曲的随机播放、循环播放等操作。

  4. 遍历一个数据库中的数据表,以便实现数据的增删改查等操作。

迭代器模式实现

下面通过Java代码来实现一个简单的迭代器模式:

抽象聚合类

package com.example.javaDesignPattern.iterator;import java.util.Iterator;/*** @Author bug菌* @Date 2023-09-19 22:31*/
public interface Aggregate {public void add(Object obj);public void remove(Object obj);public Iterator getIterator();
}

具体聚合类

package com.example.javaDesignPattern.iterator;import java.util.ArrayList;
import java.util.List;/*** @Author bug菌* @Date 2023-09-19 22:32*/
public class ConcreteAggregate implements Aggregate {private List<Object> list = new ArrayList<>();public void add(Object obj) {list.add(obj);}public void remove(Object obj) {list.remove(obj);}public ConcreteIterator getIterator() {return new ConcreteIterator(list);}
}

抽象迭代器类

package com.example.javaDesignPattern.iterator;/*** @Author bug菌* @Date 2023-09-19 22:32*/
public interface Iterator {public Object next();public boolean hasNext();
}

具体迭代器类

package com.example.javaDesignPattern.iterator;import java.util.List;/*** @Author bug菌* @Date 2023-09-19 22:32*/
public class ConcreteIterator implements Iterator {private List<Object> list;private int index = 0;public ConcreteIterator(List<Object> list) {this.list = list;}public Object next() {if (hasNext()) {return list.get(index++);}return null;}public boolean hasNext() {return index < list.size();}
}

测试代码

package com.example.javaDesignPattern.iterator;/*** @Author bug菌* @Date 2023-09-19 22:33*/
public class IteratorPatternTest {public static void main(String[] args) {Aggregate aggregate = new ConcreteAggregate();aggregate.add("aaa");aggregate.add("bbb");aggregate.add("ccc");Iterator iterator = aggregate.getIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

  在上面的代码中,我们通过抽象聚合类 Aggregate 和具体聚合类 ConcreteAggregate 封装了集合底层实现的细节,提供了一个可以遍历集合中元素的抽象方法 getIterator()。同时,我们定义了抽象迭代器类 Iterator 和具体迭代器类 ConcreteIterator,它们负责实现遍历集合中元素的具体操作,包括获取下一个元素和判断是否遍历完毕等方法。

  在测试代码中,我们创建了一个具体聚合类的实例 aggregate,并向其中添加了三个元素。然后通过调用 aggregategetIterator() 方法获取一个具体迭代器实例 iterator,并通过 while 循环遍历了集合中的所有元素。

测试结果如下:

在这里插入图片描述

附录源码

  如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

总结

  在本文中,我们介绍了迭代器模式的实现原理、代码示例和测试用例。迭代器模式是一种可以帮助我们在不暴露集合底层实现的情况下,遍历集合中的所有元素的设计模式。它将遍历集合的操作封装到一个迭代器类中,客户端只需要通过迭代器的接口就可以遍历集合中的元素。迭代器模式的优点是封装性好,支持多种遍历方法,缺点是增加了类的数量,可能会影响程序性能。通过本文的介绍,相信读者已经对迭代器模式有了更深入的理解,可以在实际开发中更

☀️建议/推荐你


  如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

📣关于我


我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

共享wifi贴项目现在到底还能不能做?

共享wifi贴作为一项新兴的业务&#xff0c;近年来在城市中越来越受欢迎。然而&#xff0c;很多人对共享wifi项目的盈利能力表示怀疑&#xff0c;不确定它是否能够持久发展。那么&#xff0c;共享wifi贴到底能不能做&#xff1f;让我来给你解答。 首先&#xff0c;共享WiFi项目可…

Pyspark案例综合(数据计算)

数据计算 map方法 map算子 map算子&#xff08;成员方法&#xff09;接受一个处理函数&#xff0c;可用lambda快速编写&#xff0c;对RDD内的元素一一处理&#xff0c;返回RDD对象 链式调用 对于返回值是新的RDD的算子&#xff0c;可以通过链式调用的方式多次调用算子 &q…

一键集成prometheus监控微服务接口平均响应时长

一、效果展示 二、环境准备 prometheus + grafana环境 参考博文:https://blog.csdn.net/luckywuxn/article/details/129475991 三、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter

身份和访问管理解决方案:混合型IAM

对于依赖于本地 IT 基础结构和传统安全模型的组织&#xff0c;可以更轻松地验证和授权企业网络内的所有内容&#xff0c;包括设备、用户、应用程序和服务器。尝试从公司网络外部获取访问权限的用户使用虚拟专用网络 &#xff08;VPN&#xff09; 和网络访问控制 &#xff08;NA…

【教程】微信小程序导入外部字体详细流程

前言 在微信小程序中&#xff0c;我们在wxss文件中通过font-family这一CSS属性来设置文本的字体&#xff0c;并且微信小程序有自身支持的内置字体&#xff0c;可以通过代码提示查看微信小程序支持字体&#xff1a; 这些字体具体是什么样式可以参考&#xff1a; 微信小程序--字…

从零学习开发一个RISC-V操作系统(一)丨计算机组成原理相关知识与RISC-V指令集简介

本篇文章的内容 一、计算机组成原理的相关知识1.1 计算机的硬件组成1.2 程序的存储与执行1.3 程序语言的设计和进化1.4 存储设备的层次结构1.5 操作系统 二、RISC-V的指令集ISA简介2.1 什么是ISA2.2 复杂指令集&#xff08;CISC&#xff09;和精简指令集&#xff08;RISC&#…

探讨基于IEC61499 的分布式 ISA Batch 控制系统

ISA SP88 是批次过程控制的标准&#xff0c;对应的IEC标准是IEC 61512。该标准中一个重要的部分是配方管理&#xff08;Recipe Management&#xff09;。 所谓配方&#xff0c;是根据批量产品的要求&#xff0c;材料设定加工工艺&#xff0c;加工流程和参数。类似于传统制造业的…

2023年以就业为目的学习Java还有必要吗?(文末送书)

目录 一、活力四射的 Java二、从零开始学会 Java三、准备工作四、基础知识五、进阶知识六、高级知识七、结语参与方式 大家好&#xff0c;我是哪吒。 文末送5本《Java编程动手学》 今天来探讨一个问题&#xff0c;现在学 Java 找工作还有优势吗&#xff1f; 在某乎上可以看到…

Cesium 测量距离

Cesium 测量距离 需求分析第一种方式&#xff1a;使用测距 Measure第二中方式&#xff1a;使用 distance&#xff0c;自己封装第三种方式&#xff1a;自己封装&#xff08;样式不太好&#xff09; 需求 实际开发中我们经常需要用到量测工具&#xff0c;而Cesium没有直接提供量…

MySQL使用C语言链接

MySQL使用C语言链接 MySQL connect接口介绍mysql_initmysql_real_connectmysql_querymysql_store_result\mysql_use_result()mysql_num_rowsmysql_num_fieldsmysql_fetch_fieldsmysql_fetch_rowmysql_close MySQL connect 使用C语言来连接数据库&#xff0c;本质上就是利用一些…

电脑桌面的复选框如何取消

电脑桌面图标的复选框如何取消 1. 概述2. 去掉图标的复选框方法结束语 1. 概述 当你拿到新的电脑开机后&#xff0c;发现桌面上软件应用的图标左上角有个小框&#xff0c;每次点击图标都会显示&#xff0c;并且点击图标时&#xff0c;小框还会打上√&#xff1b; 这个小框的…

成功解决Selenium 中116版本的chromedriver找不到问题

Selenium 中的Google&#xff08;谷歌浏览器&#xff09;最新版本chromedriver 文章目录 Selenium 中的Google&#xff08;谷歌浏览器&#xff09;最新版本chromedriver1.当前作者的谷歌浏览器版本2.当前驱动官网的最新版本3.当不想降低浏览器版本继续使用谷歌浏览器的办法 1.当…

《计算机视觉中的多视图几何》笔记(5)

5 Algorithm Evaluation and Error Analysis 本章主要讲述对算法的验证和误差分析。 概述了两种计算这种不确定性&#xff08;协方差&#xff09;的方法。第一个基于线性近似值&#xff0c;涉及串联各种雅各布表达式&#xff0c;第二个是更容易实施蒙特卡洛方法。 文章目录 …

Linux——IO

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——文件系统 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;是不是只有C/C有文件操作呢&#xff1f;python&#xff0c;java&…

Ubuntu安装中文拼音输入法

ubuntu安装中文拼音输入法 ubuntu版本为23.04 1、安装中文语言包 首先安装中文输入法必须要让系统支持中文语言&#xff0c;可以在 Language Support 中安装中文语言包。 添加或删除语音选项&#xff0c;添加中文简体&#xff0c;然后会有Applying changes的对话框&#x…

源码编译Qt 5.15.9+msvc2019

官方文档里给出了详细步骤&#xff1a; Building Qt Sources Building Qt 5 from Git (Wiki) 注&#xff1a;本文基于windows11vs2019x64qt5.15.9&#xff0c;不编译Qt WebEngine 归纳总结如下&#xff1a; 准备阶段 Qt for Windows - Requirements 安装python&#xff0c;…

逼自己看完,Redis的事务你就掌握了!!!

目录 1、对于事务的理解 1.1、回顾MySQL的事务 1.2、Redis的事务 2、事务命令使用 3、watch的实现原理 3.1、watch用来干什么的&#xff1f; 3.2、watch的实现原理 1、对于事务的理解 1.1、回顾MySQL的事务 在MySQL中&#xff0c;事务有4个特性&#xff1a; 原子性&a…

MyBatis中当实体类中的属性名和表中的字段名不一样,怎么办

方法1&#xff1a; 在mybatis核心配置文件中指定&#xff0c;springboot加载mybatis核心配置文件 springboot项目的一个特点就是0配置&#xff0c;本来就省掉了mybatis的核心配置文件&#xff0c;现在又加回去算什么事&#xff0c;总之这种方式可行但没人这样用 具体操作&…

详细介绍如何微调 YOLOv8 姿势模型以进行动物姿势估计--附完整源码

动物姿势估计是计算机视觉的一个研究领域,是人工智能的一个子领域,专注于自动检测和分析图像或视频片段中动物的姿势和位置。目标是确定一只或多只动物身体部位的空间排列,例如头部、四肢和尾巴。这项技术具有广泛的应用,从研究动物行为和生物力学到野生动物保护和监测。 …

【LeetCode-中等题】107. 二叉树的层序遍历 II

文章目录 题目方法一&#xff1a;队列层序迭代 题目 方法一&#xff1a;队列层序迭代 解题详情&#xff1a;【LeetCode-中等题】102. 二叉树的层序遍历 res.add(0,zres); //效果是将 zres 列表作为 res 的第一个子列表&#xff0c;并将其它原本在第一位置及之后的子列表向后移…