当前位置: 首页 > news >正文

【设计模式深度剖析】【5】【行为型】【迭代器模式】

👈️上一篇:策略模式    |   下一篇:中介者模式👉️

设计模式-专栏👈️

---

文章目录

  • 迭代器模式
  • 定义
    • 英文原话
    • 直译
    • 如何理解呢?
  • 迭代器模式的角色
    • 1. Iterator(迭代器)
    • 2. ConcreteIterator(具体迭代器)
    • 3. Aggregate(聚合)
    • 4. ConcreteAggregate(具体聚合)
    • 类图
    • 代码示例
  • 迭代器模式的应用
    • 迭代器模式的优点
    • 迭代器模式的缺点
    • 迭代器模式的使用场景

迭代器模式

迭代器模式(Iterator Pattern)的关键思想

将对列表的访问和遍历列表对象分离出来并放入一个迭代器(iterator)对象

迭代器模式就像是一个“导游”,它能够引导我们安全、有序地遍历集合中的“景点”,无需我们亲自去探索整个集合的内部结构。

定义

英文原话

The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

直译

迭代器模式提供了一种顺序访问聚合对象中的元素的方法,而又不需暴露该对象的内部表示。

如何理解呢?

想象一下,我们有一个装满各种水果的篮子(集合),而我们想逐一品尝每种水果(遍历元素)。但我们不希望直接把手伸进篮子里去取水果(暴露内部表示),因为这样可能会把篮子弄乱。

这时,我们可以使用一个迭代器(比如一个长柄勺),它可以帮助我们按顺序从篮子里取出水果,而不需要我们直接接触到篮子内部。每次我们用勺子取出一颗水果后,它就会指向下一个水果的位置。这样,我们就可以轻松品尝完所有的水果,同时保持篮子的整洁和有序。

迭代器模式就是这样一种工具,它让我们能够方便地遍历集合中的元素,同时保持集合的完整性和封装性。在软件开发中,这种模式的应用场景非常广泛,特别是在处理复杂数据结构时,它能够大大提高代码的可读性和可维护性。

迭代器模式的角色

迭代器模式中的角色通常包括:

1. Iterator(迭代器)

定义了访问和遍历元素的接口。

2. ConcreteIterator(具体迭代器)

实现了迭代器接口,并跟踪遍历中的当前位置。

3. Aggregate(聚合)

定义了创建迭代器对象的接口。

4. ConcreteAggregate(具体聚合)

实现了聚合接口,并返回具体迭代器的实例。

类图

在这里插入图片描述

代码示例

// 迭代器接口
interface Iterator {boolean hasNext();Object next();
}// 具体迭代器  
class ConcreteIterator implements Iterator {private List<Integer> list;private int currentIndex = 0;public ConcreteIterator(List<Integer> list) {this.list = list;}@Overridepublic boolean hasNext() {return currentIndex < list.size();}@Overridepublic Object next() {if (this.hasNext()) {return list.get(currentIndex++);}return null;}
}// 聚合接口  
interface Aggregate {Iterator createIterator();
}// 具体聚合  
class ConcreteAggregate implements Aggregate {private List<Integer> list = new ArrayList<>();public void add(Integer item) {list.add(item);}@Overridepublic Iterator createIterator() {return new ConcreteIterator(list);}
}// 客户端代码  
public class Client {public static void main(String[] args) {ConcreteAggregate aggregate = new ConcreteAggregate();// 添加一些元素到聚合对象中  for (int i = 0; i < 10; i++) {aggregate.add(i);}// 获取迭代器并遍历聚合对象  Iterator iterator = aggregate.createIterator();while (iterator.hasNext()) {System.out.print(iterator.next()+"\t");}}
}/* Output:
0	1	2	3	4	5	6	7	8	9	
*///~

在上面的示例中,我们定义了迭代器接口Iterator,它有两个方法:hasNext()用于检查是否还有下一个元素,next()用于获取下一个元素。然后,我们创建了ConcreteIterator类来实现这个接口,并跟踪当前遍历的位置。

Aggregate接口定义了创建迭代器的方法,而ConcreteAggregate类实现了这个接口,并提供了一个List来存储元素,并且有一个方法用于返回ConcreteIterator的实例。

在客户端代码中,我们创建了一个ConcreteAggregate对象,并向其中添加了一些元素。然后,我们获取了一个迭代器,并使用它来遍历聚合对象中的所有元素。

迭代器模式的应用

迭代器模式在软件开发中广泛应用于需要遍历集合对象(如列表、集合、映射等)的场景。它提供了一种统一的方式来访问集合中的元素,而不需要关心集合的内部结构和实现细节。通过迭代器,我们可以顺序地访问集合中的每一个元素,同时保持集合的封装性。

迭代器模式的优点

  1. 简化代码:通过将遍历操作封装在迭代器中,可以避免在客户端代码中编写重复的遍历逻辑,从而简化代码结构。
  2. 支持多种遍历方式:迭代器模式允许我们在不修改原有代码的情况下,通过实现不同的迭代器类来支持多种遍历方式。
  3. 隐藏内部实现:迭代器模式将集合的内部实现与遍历操作分离客户端代码只需要通过迭代器接口访问集合中的元素,无需关心集合的具体实现。
  4. 扩展性好:如果需要添加新的集合类,只需要实现对应的迭代器类即可,无需修改原有代码。

迭代器模式的缺点

  1. 类的个数成对增加:由于迭代器模式将存储数据和遍历数据的职责分离,每增加一个集合类,就需要增加一个对应的迭代器类,这在一定程度上增加了系统的复杂性。
  2. 可能增加系统开销:由于需要创建迭代器对象来遍历集合,这可能会增加一些额外的系统开销。

迭代器模式的使用场景

  1. 内容保密:当需要访问集合对象的内容,但又不希望暴露其内部表示时,可以使用迭代器模式。这样可以保持集合的封装性,同时提供一种统一的访问方式。
  2. 统一接口:当需要为不同的集合结构提供统一的遍历接口时,可以使用迭代器模式。通过实现统一的迭代器接口,可以使得客户端代码更加简洁、可复用。

---

👈️上一篇:策略模式    |   下一篇:中介者模式👉️

设计模式-专栏👈️

相关文章:

【设计模式深度剖析】【5】【行为型】【迭代器模式】

&#x1f448;️上一篇:策略模式 | 下一篇:中介者模式&#x1f449;️ 设计模式-专栏&#x1f448;️ 文章目录 迭代器模式定义英文原话直译如何理解呢&#xff1f; 迭代器模式的角色1. Iterator&#xff08;迭代器&#xff09;2. ConcreteIterator&#xff08;具体迭代器…...

怎么更快捷的修改图片大小?压缩图片jpg、png、gif的快捷方法

jpg作为最常用的一种图片格式&#xff0c;在遇到图片太大问题时&#xff0c;该如何操作能够快速在压缩图片jpg的大小呢&#xff1f;图片太大无法上传时目前常见的一个使用问题&#xff0c;只有将图片处理到合适的大小才可以正常在平台上传使用&#xff0c;一般情况下想要快速解…...

Shell脚本 if语句

条件测试&#xff1a; $? 返回码 判断命令或者脚本是否执行成功&#xff08;最近的一条&#xff09; 0 true 为真就是成功 成立 非0 false 失败或者异常 test命令 可以进行条件测试 然后根据的是返回值来判断条件是否成立。 -e 测试目录或者文件是否存在 exist -d 测试…...

集合查询-并(UNION)集运算、交(INTERSECT)集运算、差(EXCEPT)集运算

一、概述 集合查询是对两个SELECT语句的查询结果进行再进行处理的查询 二、条件 1、两个SELECT语句的查询结果必须是属性列数目相同 2、两个SELECT语句的查询结果必须是对应位置上的属性列必须是相同的数据类型 三、并(UNION)运算 1、语法格式&#xff1a; SELECT 语句1…...

常用的bit位操作

//判断某1位是1还是0 #ifndef GET_BIT #define BIT_IS_1(value,bitpos) (((value)&(1<<(bitpos)))>>(bitpos)) #endif //读取指定位置bit位的值 #ifndef GET_BIT #define GET_BIT(value,bitpos) ((value)&(1<<(bitpos))) #endif //取反指定位置bit位…...

自动控制原理【期末复习】(二)

无人机上桨之后可以在调试架上先调试&#xff1a; 1.根轨迹的绘制 /// 前面针对的是时域分析&#xff0c;下面针对频域分析&#xff1a; 2.波特图 3.奈维斯特图绘制 1.奈氏稳定判据 2.对数稳定判据 3.相位裕度和幅值裕度...

机器学习——集成学习和梯度提升决策树

集成学习 不同的算法都可以对解决同一个问题&#xff0c;但是可能准确率不同&#xff0c;集成学习就是不同算法按照某种组合来解决问题&#xff0c;使得准确率提升。 那怎么组合算法呢&#xff1f; 自举聚合算法**&#xff08;bagging&#xff09;** 顾名思义是 自举聚合 自举…...

MYSQL 查看SQL执行计划

一、explain explain select id,db,user,host,command,time,state,info from information_schema.processlist order by time desc; id: 查询的标记&#xff0c;可以查看不同查询的执行顺序。 select_type: 查询的类型&#xff0c;如SIMPLE、SUBQUERY、PRIMARY等。 table: …...

ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的MPAM

安全之安全(security)博客目录导读 关于RME的MPAM变化的完整定义见在《Arm Architecture Reference Manual Supplement, Memory System Resource Partitioning and Monitoring (MPAM), for A-profile architecture》中详细说明。 实现RME的处理元件(PE)能够生成一个2位的MPAM_…...

cuda 架构设置

import torch torch.cuda.get_device_capability(0) 添加cmake options&#xff1a; -DCMAKE_CUDA_ARCHITECTURES86 -DCMAKE_CUDA_COMPILER/usr/local/cuda-11.8/bin/nvcc cmake工程出现“CMAKE_CUDA_ARCHITECTURES must be non-empty if set.“的解决方法_failed to detec…...

基于 Vue 3 封装一个 ECharts 图表组件

在前端开发中&#xff0c;数据可视化是展示数据的重要方式之一。ECharts 是一个强大的开源可视化库&#xff0c;能够帮助我们轻松地创建各种图表。本文将介绍如何在 Vue 3 项目中使用 ECharts 封装一个图表组件。 代码 <template><div ref"chartRef" styl…...

LeetCode 算法: 旋转图像c++

原题链接&#x1f517;&#xff1a; 旋转图像 难度&#xff1a;中等⭐️⭐️ 题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图…...

Java Android 静态内部类 以及优雅实现单例模式/避免handler内存泄漏

前言 Java 中的静态内部类(Static Nested Class)是定义在另一个类里面的一个静态类。它和普通的内部类有些区别,主要是静态内部类不需要依赖于外部类的实例就可以被创建和访问。这种类的特性使得它非常适合用来作为辅助类,用于支持外部类的功能。 特点以及使用场景 静态内…...

Flink协调器Coordinator及自定义Operator

Flink协调器Coordinator及自定义Operator 最近的项目开发过程中&#xff0c;使用到了Flink中的协调器以及自定义算子相关的内容&#xff0c;本篇文章主要介绍Flink中的协调器是什么&#xff0c;如何用&#xff0c;以及协调器与算子间的交互。 协调器Coordinator Flink中的协调…...

C调用C++中的类

文章目录 测试代码 测试代码 在C语言中调用C类&#xff0c;需要遵循几个步骤&#xff1a; 在C代码中&#xff0c;确保C类的函数是extern “C”&#xff0c;这样可以防止名称修饰&#xff08;name mangling&#xff09;。 使用头文件声明C类的公共接口&#xff0c;并且为这个…...

NFTScan 正式上线 Sei NFTScan 浏览器和 NFT API 数据服务

2024 年 6 月 12 号&#xff0c;NFTScan 团队正式对外发布了 Sei NFTScan 浏览器&#xff0c;将为 Sei 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Sei 是继 Bitcoin、Ethereum、BNBChain、Polyg…...

2024年高考:计算机相关专业前景分析与选择建议

2024年高考结束&#xff0c;面对计算机专业是否仍具有吸引力的讨论&#xff0c;本文将从行业趋势、就业市场、个人兴趣与能力、专业选择建议等多个角度进行深入分析&#xff0c;以帮助考生和家长做出明智的决策。 文章目录 一、行业趋势与就业市场1. 计算机行业的发展与变革2. …...

SQL聚合函数---汇总数据

此篇文章内容均来自与mysql必知必会教材&#xff0c;后期有衍生会继续更新、补充知识体系结构 文章目录 SQL聚集函数表&#xff1a;AGV()count()根据需求可以进行组合处理 max()min()max&#xff08;&#xff09;、min&#xff08;&#xff09;、avg&#xff08;&#xff09;组…...

webpack5新特性

webpack5新特性 持久化缓存资源模块moduleIds & chunkIds的优化更智能的tree shakingnodeJs的polyfill脚本被移除支持生成e6/es2015的代码SplitChunk和模块大小Module Federation 持久化缓存 缓存生成的webpack模块和chunk,来改善构建速度cache 会在开发模式被设置成 ty…...

java单体服务自定义锁名称工具类

需求&#xff1a; 操作员能够对自己权限下的用户数据进行数据填充&#xff0c;但是不同操作员之间可能会有重复的用户数据&#xff0c;为了避免操作员覆盖数据或者重复操作数据&#xff0c;应该在操作用户数据时加锁&#xff0c;要求加的这一把锁必须是细粒度的锁&#xff0c;…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...