迭代器模式介绍

目录

一、迭代器模式介绍

1.1 迭代器模式定义

1.2 迭代器模式原理

1.2.1 迭代器模式类图

1.2.2 模式角色说明

1.2.3 示例代码

二、迭代模式的应用

2.1 需求说明

2.2 需求实现

2.2.1 抽象迭代类

2.2.2 抽象集合类

2.2.3 主题类

2.2.4 具体迭代类

2.2.5 具体集合类

2.2.6 测试类

三、迭代器模式总结

3.1 迭代器模式的优点

3.2 迭代器模式的缺点

3.3 迭代器模式的使用场景


一、迭代器模式介绍

1.1 迭代器模式定义

迭代器模式(Iterator pattern)又叫游标(Cursor)模式,它的原始定义是:迭代器提供一种对容器对象中的各个元素进行访问的方法,而又不需要暴露该对象的内部细节。

迭代器模式是我们学习一个设计时很少用到的、但编码实现时却经常使用到的行为型设计模式。在绝大多数编程语言中,迭代器已经成为一个基础的类库,直接用来遍历集合对象。在平时开发中,我们更多的是直接使用它,很少会从零去实现一个迭代器。

在软件系统中,容器对象拥有两个职责:一是存储数据,而是遍历数据。从依赖性上看,前者是聚合对象的基本职责。而后者是可变化的,又是可分离的。因此可以将遍历数据的行为从容器中抽取出来,封装到迭代器对象中,由迭代器来提供遍历数据的行为,这将简化聚合对象的设计,更加符合单一职责原则。

1.2 迭代器模式原理

1.2.1 迭代器模式类图

1.2.2 模式角色说明

迭代器模式主要包含以下角色:

  • 抽象集合(Aggregate)角色:用于存储和管理元素对象, 定义存储、添加、删除集合元素的功能,并且声明了一个createIterator()方法用于创建迭代器对象。
  • 具体集合(ConcreteAggregate)角色:实现抽象集合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含hasNext()、next() 等方法。
  1. hasNext()函数用于判断集合中是否还有下一个元素。
  2. next() 函数用于将游标后移一位元素。
  3. currentItem() 函数,用来返回当前游标指向的元素。
  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对集合对象的遍历,同时记录遍历的当前位置。

1.2.3 示例代码

package main.java.cn.test.iterator.V1;/*** @author ningzhaosheng* @date 2024/1/15 15:23:06* @description 迭代器接口*/
public interface Iterator<E> {//判断集合中是否有下一个元素boolean hasNext();//将游标后移一位元素void next();//返回当前游标指定的元素E currentItem();
}
package main.java.cn.test.iterator.V1;import java.util.ArrayList;
import java.util.NoSuchElementException;/*** @author ningzhaosheng* @date 2024/1/15 15:23:43* @description 具体迭代器*/
public class ConcreteIterator<E> implements Iterator<E> {//游标private int cursor;//容器private ArrayList<E> arrayList;public ConcreteIterator(ArrayList<E> arrayList) {this.cursor = 0;this.arrayList = arrayList;}@Overridepublic boolean hasNext() {return cursor != arrayList.size();}@Overridepublic void next() {cursor++;}@Overridepublic E currentItem() {if (cursor >= arrayList.size()) {throw new NoSuchElementException();}return arrayList.get(cursor);}
}
package main.java.cn.test.iterator.V1;import java.util.ArrayList;/*** @author ningzhaosheng* @date 2024/1/15 15:25:35* @description 测试类*/
public class Test {public static void main(String[] args) {ArrayList<String> names = new ArrayList<>();names.add("lisi");names.add("zhangsan");names.add("wangwu");Iterator<String> iterator = new ConcreteIterator(names);while (iterator.hasNext()) {System.out.println(iterator.currentItem());iterator.next();}/*** 使用ArrayList集合中的iterator()方法获取迭代器* 将创建迭代器的方法放入集合容器中,这样做的好处是对客户端封装了迭代器的实现细节.*/java.util.Iterator<String> iterator1 = names.iterator();while (iterator1.hasNext()) {System.out.println(iterator1.next());iterator.next();}}
}

二、迭代模式的应用

2.1 需求说明

为了帮助大家更好地理解迭代器模式,下面我还是通过一个简单的例子给大家演示一下

2.2 需求实现

2.2.1 抽象迭代类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:30:18* @description 抽象迭代器 IteratorIterator*/
public interface IteratorIterator<E> {//重置为第一个元素void reset();//获取下一个元素E next();//检索当前元素E currentItem();//判断是否还有下一个元素存在boolean hasNext();
}

2.2.2 抽象集合类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:31:11* @description 抽象集合类*/
public interface ListList<E> {//获取迭代器对象的抽象方法(面向接口编程)IteratorIterator<E> Iterator();
}

2.2.3 主题类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:31:52* @description 主题类*/
public class Topic {private String name;public Topic(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

2.2.4 具体迭代类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:32:22* @description 具体迭代类*/
public class TopicIterator implements IteratorIterator<Topic> {//Topic数组private Topic[] topics;//记录存储位置private int position;public TopicIterator(Topic[] topics) {this.topics = topics;position = 0;}@Overridepublic void reset() {position = 0;}@Overridepublic Topic next() {return topics[position++];}@Overridepublic Topic currentItem() {return topics[position];}@Overridepublic boolean hasNext() {if (position >= topics.length) {return false;}return true;}
}

2.2.5 具体集合类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:33:55* @description 具体集合类*/
public class TopicList implements ListList<Topic> {private Topic[] topics;public TopicList(Topic[] topics) {this.topics = topics;}@Overridepublic IteratorIterator<Topic> Iterator() {return new TopicIterator(topics);}
}

2.2.6 测试类

package main.java.cn.test.iterator.V2;/*** @author ningzhaosheng* @date 2024/1/15 15:35:00* @description 测试类*/
public class Test {public static void main(String[] args) {Topic[] topics = new Topic[4];topics[0] = new Topic("topic1");topics[1] = new Topic("topic2");topics[2] = new Topic("topic3");topics[3] = new Topic("topic4");TopicList topicList = new TopicList(topics);IteratorIterator<Topic> iterator = topicList.Iterator();while (iterator.hasNext()) {Topic t = iterator.next();System.out.println(t.getName());}}
}

三、迭代器模式总结

3.1 迭代器模式的优点

  • 迭代器模式支持以不同方式遍历一个集合对象,在同一个集合对象上可以定义多种遍历方式。 在迭代器模式中只需要用一个不同的迭代器来替换原有的迭代器,即可改变遍历算法,也可以自己定义迭代器的子类以支持新的遍历方式。
  • 迭代器简化了集合类。由于引入了迭代器,在原有的集合对象中不需要再自行提供数据遍历等方法,这样可以简化集合类的设计。
  • 在迭代器模式中,由于引入了抽象层,增加新的集合类和迭代器类都很方便,无须修改原有代码,满足 "基于接口编程而非实现" 和 "开闭原则" 的要求。

3.2 迭代器模式的缺点

  • 由于迭代器模式将存储数据和遍历数据的职责分离,增加了类的个数,这在一定程度上增加了系统的复杂性。
  • 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。

3.3 迭代器模式的使用场景

  • 减少程序中重复的遍历代码。

对于放入一个集合容器中的多个对象来说,访问必然涉及遍历算法。如果我们不将遍历算法封装到容器里(比如,List、Set、Map 等),那么就需要使用容器的人自行去实现遍历算法,这样容易造成很多重复的循环和条件判断语句出现,不利于代码的复用和扩展,同时还会暴露不同容器的内部结构。而使用迭代器模式是将遍历算法作为容器对象自身的一种“属性方法”来使用,能够有效地避免写很多重复的代码,同时又不会暴露内部结构。

  • 当需要为遍历不同的集合结构提供一个统一的接口时或者当访问一个集合对象的内容而无须暴露其内部细节的表示时。

迭代器模式把对不同集合类的访问逻辑抽象出来,这样在不用暴露集合内部结构的情况下,可以隐藏不同集合遍历需要使用的算法,同时还能够对外提供更为简便的访问算法接口。

好了,本次分享就到这里,欢迎大家继续阅读《设计模式》专栏其他设计模式内容,如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!

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

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

相关文章

tcp/ip协议2实现的插图,数据结构7 (27 - 章)

(166) 166 二七1 TCP的函数 函tcp_drain,tcp_drop (167) (168)

Windows WSL2 占用磁盘空间清理释放

目前工作中时常用到WSL2&#xff08;Ubuntu20.04&#xff09;&#xff0c;在使用一段时间后会发现WSL2所占用磁盘空间越来越多&#xff0c;体现在WSL2之上安装Linux分发对应的vhdx虚拟磁盘文件体积越来越大&#xff0c;会占用Windows自身空间&#xff0c;即使手动清理了Linux分…

GD32E230C8T6《调试篇》之 (软件) IIC通信(主机接收从机) + GN1650驱动芯片 + 按键 + 4位8段数码管显示 (成功)

GD32E230C8T6《调试篇》之 &#xff08;软件&#xff09; IIC通信 GN1650驱动芯片 4位8段数码管显示&#xff08;成功&#xff09; IIC是什么IIC简介1&#xff09;IIC总线物理连接2&#xff09;IIC时序协议 按键扫描代码1&#xff09;DIG2短按只一次&#xff0c;长按超过1s 一…

若依微服务框架,富文本加入图片保存时出现JSON parse error: Unexpected character (‘/‘ (code 47)):...

若依微服务框架&#xff0c;富文本加入图片保存时出现JSON parse error: Unexpected character 一、问题二、解决1.修改网关配置2、对数据进行加密解密2.1安装插件2.2vue页面加密使用2.3后台解密存储 一、问题 若依微服务项目在使用富文本框的时候&#xff0c;富文本加入图片进…

【Java程序员面试专栏 专业技能篇】MySQL核心面试指引(一):基础知识考察

关于MySQL部分的核心知识进行一网打尽,包括三部分:基础知识考察、核心机制策略、性能优化策略,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 本篇Blog为第一部分:基础知识考察,子节点表示追问或同级提问 基本概念 包括一些核心问…

ARMv8-AArch64 的异常处理模型详解之异常类型 Exception types

异常类型详解 Exception types 一&#xff0c; 什么是异常二&#xff0c;同步异常&#xff08;synchronous exceptions&#xff09;2.1 无效的指令和陷阱异常&#xff08;Invalid instructions and trap exceptions&#xff09;2.2 内存访问产生的异常2.3 产生异常的指令2.4 调…

基于JavaWeb+SSM+Vue智能社区服务小程序系统的设计和实现

基于JavaWebSSMVue智能社区服务小程序系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相…

【排序算法】六、快速排序(C/C++)

「前言」文章内容是排序算法之快速排序的讲解。&#xff08;所有文章已经分类好&#xff0c;放心食用&#xff09; 「归属专栏」排序算法 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 快速排序1.1 原理1.2 Hoare版本&#xff08;单趟&#xff09;1.3 快速排序完整代码&…

Excel 根据日期按月汇总公式

Excel 根据日期按月汇总公式 数据透视表日期那一列右击&#xff0c;选择“组合”&#xff0c;步长选择“月” 参考 Excel 根据日期按月汇总公式Excel如何按着日期来做每月求和

Linux内存管理:(九)内存规整

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 引言 伙伴系统以页面为单位来管…

leetcode:每日温度---单调栈

题目&#xff1a; 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例&…

天龙八部资源提取工具(提取+添加+修改+查看+教程)

可以提取&#xff0c;添加&#xff0c;修改&#xff0c;查看天龙八部里面的数据。非常好用。 天龙八部资源提取工具&#xff08;提取添加修改查看教程&#xff09; 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1XOMJ1xvsbD-UUQOv3QfHPQ?pwd0kd0 提取码&…

赛车游戏简单单车C语言版

#include<stdio.h> #include<easyx.h> #include<time.h>#define WIDTH 512 #define HEIGHT 768//定义一个汽车类 struct FCar {//坐标float x, y;// 汽车种类int type;//汽车速度float speed; };//定义全局变量 图片坐标 IMAGE BG_IMG; //背景图片坐标 float…

logstack 日志技术栈-04-opensource 开源工具 SigNoz+Graylog

3. SigNoz SigNoz 是一个日志收集和分析工具&#xff0c;可以收集和管理来自各种来源的日志、指标、跟踪和异常。 它为使用 OpenTelemetry 检测应用程序提供本机支持&#xff0c;以防止供应商锁定&#xff0c;将收集到的数据存储在 ClickHouse 中&#xff0c;然后在用户友好的…

【实战】SpringBoot自定义 starter及使用

文章目录 前言技术积累SpringBoot starter简介starter的开发步骤 实战演示自定义starter的使用写在最后 前言 各位大佬在使用springboot或者springcloud的时候都会根据需求引入各种starter&#xff0c;比如gateway、feign、web、test等等的插件。当然&#xff0c;在实际的业务…

灵活扩展:深入理解MyBatis插件机制

第1章&#xff1a;MyBatis插件的重要性 大家好&#xff0c;我是小黑&#xff0c;咱们今天要聊的是MyBatis插件&#xff0c;MyBatis&#xff0c;大家都不陌生&#xff0c;它是一个ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;让咱们在操作数据库时能更加优雅。但今…

web漏洞总结大全(基础)

前言 本文章是和cike_y师傅一起写的&#xff0c;cike_y博客&#xff1a;https://blog.csdn.net/weixin_53912233?typeblog 也欢迎大家对本文章进行补充和指正&#xff0c;共同维护这个项目&#xff0c;本文的github项目地址&#xff1a; https://github.com/baimao-box/Sum…

Haxe-UnrealEngine5

Haxe-UnrealEngine5 结论 UE C header > External/**.hx.hx > .h/.cpp&#xff0c;和 UE C 一起编译使用 hxcpp 来调试 .hx good&#xff1a; 理论上不仅限反射代码走 UE C&#xff0c;无需维护 backend&#xff0c;比如 Lua Binding理论上接近 UE C 的性能 bad&…

六、Netty核心模块组件

目录 6.1 BootStrap&#xff0c;ServerBootStrap6.2 Future&#xff0c;ChannelFuture6.3 Channel6.4 Selector6.5 ChannelHandler 以及其实现类6.6 Pipeline 和 ChannelPipeline6.7 ChannelHandlerContext6.8 ChannelOption6.9 EventLoopGroup和其实现类 NioEventLoopGroup6.1…

激光无人机打击系统——光束控制和指向系统

激光无人机&#xff08;UAV&#xff09;打击系统中的光束控制和指向系统通常包括以下几个关键组件和技术&#xff1a; 激光发射器&#xff1a;这是系统的核心&#xff0c;负责生成高能量的激光束。常用的激光类型包括固体激光器、化学激光器、光纤激光器等&#xff0c;选择取决…