迭代器模式(十九)

news2024/10/7 16:17:16

相信自己,请一定要相信自己

上一章简单介绍了访问者模式(十八), 如果没有看过, 请观看上一章

一. 迭代器模式

引用 菜鸟教程里面迭代器模式介绍: https://www.runoob.com/design-pattern/iterator-pattern.html

迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。

这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。

迭代器模式属于行为型模式。

一.一 介绍

意图: 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

主要解决: 不同的方式来遍历整个整合对象。

何时使用: 遍历一个聚合对象。

如何解决: 把在元素之间游走的责任交给迭代器,而不是聚合对象。

关键代码: 定义接口:hasNext, next。

应用实例: JAVA 中的 iterator。

优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点: 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

使用场景: 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。

注意事项: 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。


组成角色具体关系
IteratorMyIterator迭代器接口,是系统提供,含义 hasNext, next, remove
ConcreteIteratorBookShelfIterator,BookShelfReverseIterator具体的迭代器类,管理迭代
AggregateAggregate一个统一的聚合接口, 将客户端和具体聚合解耦
ConcreteAggreageBookShelf具体的聚合持有对象集合, 并提供一个方法,返回一个迭代器, 该迭代器可以正确遍历 集合

image-20230615174455088

二. 迭代器实例

二.一 迭代的实体对象 Book

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Serializable {
    private String name;
    private String author;
}

二.二 迭代器接口 MyIterator

可以直接使用 java 提供的 java.util.Iterator 接口

public interface MyIterator<T> {
    public boolean hasNext();

    public T next() ;

}

二.三 聚合接口 Aggregate

定义了两个迭代器

public interface Aggregate<T> {

    /**
     定义不同的迭代器
     */

    public MyIterator<T> getInterator();

    public MyIterator<T> getReverseInterator();


}

二.四 迭代器实现 BookShelfIterator

二.四.一 正序迭代器

public class BookShelfIterator implements MyIterator<Book>{
    private BookShelf bookShelf;

    private int index = 0;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
    }
    @Override
    public boolean hasNext() {
        return bookShelf.getLength() > index;
    }

    @Override
    public Book next() {
        Book bookAt = bookShelf.getBookAt(index);
        index++;
        return bookAt;
    }

}

二.四.二 倒序迭代器

public class BookShelfReverseIterator implements MyIterator<Book>{
    private BookShelf bookShelf;

    private int index = -1;

    public BookShelfReverseIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = bookShelf.getLength()-1;
    }
    @Override
    public boolean hasNext() {
        return index >= 0;
    }

    @Override
    public Book next() {
        Book bookAt = bookShelf.getBookAt(index);
        index--;
        return bookAt;
    }

}

二.五 具体聚合接口 BookShelf

public class BookShelf implements Aggregate<Book>{
    private List<Book> bookList = new ArrayList<>();

    @Override
    public MyIterator<Book> getInterator() {
        return new BookShelfIterator(this);
    }

    @Override
    public MyIterator<Book> getReverseInterator() {
        return new BookShelfReverseIterator(this);
    }

    public Integer getLength() {
        return bookList.size();
    }

    public void appendBook(Book book) {
        this.bookList.add(book);
    }
    public Book getBookAt(Integer position) {
        return this.bookList.get(position);
    }
}

二.六 客户端调用

@Test
    public void oneTest() {
        BookShelf bookShelf = new BookShelf();
        bookShelf.appendBook(new Book("第一本书","第一本书"));
        bookShelf.appendBook(new Book("第二本书","第二本书"));
        bookShelf.appendBook(new Book("第三本书","第三本书"));
        bookShelf.appendBook(new Book("第四本书","第四本书"));
        bookShelf.appendBook(new Book("第五本书","第五本书"));

        MyIterator<Book> interator = bookShelf.getInterator();
        while (interator.hasNext()) {
            Book book = interator.next();
            log.info("打印信息: {}", book);
        }

        // 打印反转的信息.
        log.info(">>>> 倒序的信息");

        MyIterator<Book> reverseInterator = bookShelf.getReverseInterator();
        while (reverseInterator.hasNext()) {
            Book book = reverseInterator.next();
            log.info("打印信息: {}", book);
        }
    }

image-20230615175210079

在 Java 中 集合迭代的话,是很方便的

正序迭代:

@Test
    public void twoTest() {
        List<Book> bookList = new ArrayList<>();
        bookList.add(new Book("第一本书","第一本书"));
        bookList.add(new Book("第二本书","第二本书"));
        bookList.add(new Book("第三本书","第三本书"));
        bookList.add(new Book("第四本书","第四本书"));
        bookList.add(new Book("第五本书","第五本书"));


        Iterator<Book> iterator = bookList.iterator();
        while (iterator.hasNext()) {
            Book book = iterator.next();
            log.info("打印信息: {}", book);
        }

    }

image-20230615175317809

优点

  1. 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了。

  2. 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成。

  3. 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任原则)。

在聚合类中,我们把 迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,这样一来集合改变的话,只影响到聚合对象。 而如果遍历方式改变的话,只影响到了迭代器。
4) 当要展示一组相似对象,或者遍历一组相同对象时使用, 适合使用迭代器模式

缺点

  1. 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类

本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Iterator


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

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

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

相关文章

实战:私有化部署ngin+文件步骤记录

这里写目录标题 背景准备总结 背景 出差到某国企进行私有化部署&#xff0c;一波三折。没想到是那种最麻烦的部署&#xff0c;导入文件需要刻光盘&#xff0c;进入电脑房需要上交手机&#xff0c;不允许有人以及拍摄设备&#xff0c;内部有监控摄像头。 有问题怎么办&#xf…

SYSU程设c++(第十六周)

set set<int> st; 会自动排序升序 如果降序可以set<int, greater<int>> s; map map<string,int> m; 会按键进行升序 m["uiui"]100; map<string,int>::iterator it; for(itm.begin();it!m.end();it){ cout<<"键&qu…

Spark大数据处理学习笔记(3.3)掌握RDD分区

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/OmCQ8】 文章目录 一、概念二、自定义分区器2.1 提出问题2.2 解决问题1. 准备数据文件2. 新建科目分区器3. 测试科目分区器 三、课后作业 一、概念 在Spark中&#xff0c;RDD&#xff08;弹性分布…

长文|基于Zabbix的可观测性监控

01 可观测性与可观测性监控 02 基于ZABBIX的可观测性监控 03 可观测性监控的探索 ——王小东&#xff0c;多年运维老兵&#xff0c;《nginx应用与运维实战》作者 本文整理自王小东在2022Zabbix峰会演讲分享。ppt可在公众号后台回复“ppt"。 1、可观测性与可观测性监控…

拷贝构造函数

拷贝构造函数 以值传递的方式调用函数时&#xff0c;如果实参为对象&#xff0c;会调用拷贝构造函数。函数以值的方式返回对象时&#xff0c;可能会调用拷贝构造函数&#xff08;VS会调用&#xff0c;Linux不会&#xff0c;g编译器做了优化&#xff09; 类似于构造函数和析构函…

Python控制流程盘点及高级用法、神秘技巧大揭秘!

在这篇文章中我们将全面深入地介绍 Python 的控制流程&#xff0c;包括条件语句、循环结构和异常处理等关键部分&#xff0c;尤其会将列表解析、生成器、装饰器等高级用法一网打尽。此外&#xff0c;我还将分享一些独特的见解和研究发现&#xff0c;希望能给你带来新的启发。文…

让你不再疑惑图片翻译怎么弄

你是否曾遇到过在阅读外语文章或资料时&#xff0c;遇到了图片上的文字无法翻译的困扰&#xff1f;别担心&#xff0c;如果你还不知道如何翻译图片上的文字的话&#xff0c;接下来我将教你三种图片翻译的实用小技巧&#xff0c;一起来看看吧。 翻译图片的实用方法一&#xff1a…

Python语法基础01(列表,元组,字典)

Python基础语法 变量的命名与使用 变量名只能包含字母、数字和下划线&#xff0c;只能以字母和下划线为开头不能包含空格不能使用python保留字 列表&#xff0c;元组&#xff0c;字典 列表 定义列表(元素之间可以没有任何关系)&#xff1a;[] 例如 fruits["apple&qu…

oracle如何才能卸载干净

windows系统下oracle如何才能卸载干净 1.关闭oracle所有的服务。2.删除注册表中相关信息3.删除注册表中相关Oracle安装信息4.删除注册的oracle事件日志5.删除环境变量path中关于oracle的内容6.重新启动操作系统7.删除Oracle_Home下的所有数据8.删除oracle安装目录。9.删除开始菜…

灰度图像逻辑运算之逻辑或

目录 note code test note out max(x1,x2) code void img_logic_or_fun(uchar& in1, uchar& in2, uchar& out) {out in1 > in2 ? in1 : in2; } void img_logic_or(Mat& src1, Mat& src2, Mat& res) {if (src1.size() ! src2.size()) {retur…

基于html+css的图展示128

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

【微信支付】微信v3支付案例,SpringBoot集成IJPay实现微信v3支付

前言 这篇文章主要实现一下通过IJPay来实现微信v3支付案例&#xff0c;本篇文章使用的是JSAPI即小程序支付 IJPay码云仓库&#xff1a;https://gitee.com/javen205/IJPay/tree/dev IJPay官方文档&#xff1a;https://javen205.gitee.io/ijpay/ 准备工作 导入依赖 <depen…

Python学习48:简易英汉字典

类型&#xff1a;字典‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 描述‪‬‪‬…

SpringBoot+Mybatis 实现长字符串保存和更新

数据库字段&#xff0c;写成长字符 插入xml&#xff0c;注意两个点&#xff0c;否则会报错 1、长字符串字段不能写if判断&#xff1a;<if test"name ! null and name ! "> 2、插入的时候做字符串转码&#xff1a;<![CDATA[#{fileCode}]]> <insert …

验证FeignClient类型:FeignClient集成OkHttp

验证FeignClient类型 验证FeignClient类型 验证FeignClient类型 在SynchronousMethodHandler类中查看client类型

【自监督学习1】SimCLR论文阅读

文章目录 一、摘要二、引言三、方法3.1 主要框架3.2 训练一个大的batchsize 四、数据增强4.1 实验一 数据增强的组合对学习好的特征表达非常重要4.2 对比学习需要更多的数据增强 五、一些实验证明5.1 大模型更有利于无监督对比学习5.2 非线性层的预测头增加了特征表示5.3可调节…

字符设备实现内部驱动原理及分步注册流程

字符设备实现内部驱动原理&#xff1a; 应用层&#xff1a;open函数回调到驱动中open操作方法的路线&#xff1a; open&#xff08;&#xff09;--->sys_open()--->struct inode结构体--->struct cdev结构体--->struct file_operations结构体--->mycdev_open()…

RVEA多目标优化

A Reference Vector Guided Evolutionary Algorithm for Many-objective Optimization 目标函数预备知识参考向量引导选择更新参考向量流程整体框架参考向量引导选择参考向量自适应 for Many-objective Optimization) 目标函数 min ⁡ X f ( X ) ( f 1 ( X ) , f 2 ( X ) , . …

游泳耳机买什么牌子好一点?推荐四款出色的游泳耳机

游泳和跑步类似&#xff0c;短距离冲刺时&#xff0c;大脑没什么想法&#xff0c;而中长距离的有氧运动时&#xff0c;肉体是疲惫的&#xff0c;大脑是异常清晰的&#xff0c;时间却是格外难熬的。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#xff0c;这是我从孩子时期就…

从零开始 Spring Boot 41:事件

从零开始 Spring Boot 41&#xff1a;事件 图源&#xff1a;简书 (jianshu.com) Spring 实现了一个简单、实用的事件框架&#xff0c;利用它我们可以在多个组件之间进行松耦合式的通信。 简单示例 让我们从一个简单的示例开始&#xff1a; public record Email(String addr…