迭代器模式介绍

目录

一、迭代器模式介绍

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

    @Override
    public boolean hasNext() {
        return cursor != arrayList.size();
    }

    @Override
    public void next() {
        cursor++;
    }

    @Override
    public 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;
    }


    @Override
    public void reset() {
        position = 0;
    }

    @Override
    public Topic next() {
        return topics[position++];
    }

    @Override
    public Topic currentItem() {
        return topics[position];
    }

    @Override
    public 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;
    }

    @Override
    public 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 等),那么就需要使用容器的人自行去实现遍历算法,这样容易造成很多重复的循环和条件判断语句出现,不利于代码的复用和扩展,同时还会暴露不同容器的内部结构。而使用迭代器模式是将遍历算法作为容器对象自身的一种“属性方法”来使用,能够有效地避免写很多重复的代码,同时又不会暴露内部结构。

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

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

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

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

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

相关文章

android使用相机 intent.resolveActivity returns null

问题 笔者使用java进行android开发&#xff0c;启动相机时 intent.resolveActivity returns null takePictureIntent.resolveActivity(getPackageManager()) null详细问题 笔者使用如下代码启动相机 // 启动相机SuppressLint("LongLogTag")private void dispatc…

基于华为MRS3.2.0实时Flink消费Kafka落盘至HDFS的Hive外部表的调度方案

文章目录 1 Kafka1.1 Kerberos安全模式的认证与环境准备1.2 创建一个测试主题1.3 消费主题的接收测试 2 Flink1.1 Kerberos安全模式的认证与环境准备1.2 Flink任务的开发 3 HDFS与Hive3.1 Shell脚本的编写思路3.2 脚本测试方法 4 DolphinScheduler 该需求为实时接收对手Topic&a…

yum下载源,vim使用

文章目录 yum本地配置lzrsz命令行互传scp(远程拷贝)vim yum本地配置 [rootiZf8z3j2ckkap6ypn717msZ ~]# pwd /root [rootiZf8z3j2ckkap6ypn717msZ ~]# ls /etc/yum.repos.d CentOS-Base.repo epel.repo //本地配置源yum会根据/etc/yum.repo.d路径下的配置文件来构成自己的下载…

一个简单的ETCD GUI工具

使用ETCD没有好用的GUI工具&#xff0c;随手用c#写了一个&#xff0c; 做得好玩的一个ETCD GUI工具&#xff0c;后面加上CLI 工具&#xff0c;类似于 redis Cli工具一样&#xff0c;简化在 Linux下面的操作&#xff0c;不知道有没有必要&#xff0c; git 地址如下&#xff0c;…

华为OD机试 - 查找一个有向网络的头节点和尾节点(Java JS Python C)

题目描述 给定一个有向图,图中可能包含有环,图使用二维矩阵表示,每一行的第一列表示起始节点,第二列表示终止节点,如 [0, 1] 表示从 0 到 1 的路径。 每个节点用正整数表示。 求这个数据的首节点与尾节点,题目给的用例会是一个首节点,但可能存在多个尾节点。同时图中…

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

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

leetcode下一个更大的元素---1暴力---2单调栈

1.题目&#xff1a; nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 &#xff0c;下标从 0 开始计数&#xff0c;其中nums1 是 nums2 的子集。 对于每个 0 < i < nums1.l…

苹果眼镜(Vision Pro)的开发者指南(1)

一、用到的底层核心框架&#xff1a; SwiftUI&#xff1a;无论开发者是要创建窗口、体积还是空间体验&#xff0c;SwiftUI 都是构建新的 visionOS 应用程序或将现有 iPadOS 或 iOS 应用程序引入平台的最佳方式。凭借全新的 3D 功能以及对深度、手势、效果和沉浸式场景类型的支…

C++类与对象【多态】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;C从基础到进阶 &#x1f384;1 多态&#x1f355;1.1 多态的基本概念&#x1f355;1.2 多态案例一-计算器类&#x1f355;1.3 纯虚函数和抽象类&#x1f355;1.4 多态案例二-制作饮品&…

【华为GAUSS数据库】IDEA连接GAUSS数据库方法

背景&#xff1a;数据库为华为gauss for opengauss 集中式数据库 IDEA提供了丰富的各类型数据库驱动&#xff0c;但暂未提供Gauss数据库。可以通过以下方法进行连接。 连接后&#xff0c; 可以自动检查xml文件中的sql语句是否准确&#xff0c;表名和字段名是否正确还可以直接在…

数学建模常见算法的通俗理解(2)

目录 6 K-Means&#xff08;K-均值&#xff09;聚类算法&#xff08;无需分割数据即可分类&#xff09; 6.1 粗浅理解 6.2 算法过程 6.2.1 选定质心 6.2.2 分配点 6.2.3 评价 7 KNN算法&#xff08;K近邻算法&#xff09;&#xff08;K个最近的决定方案&#xff09; 7.…

第 122 场 LeetCode 双周赛题解

A 将数组分成最小总代价的子数组 I 枚举&#xff1a;枚举后两个子数组的起始下标 class Solution { public:int minimumCost(vector<int> &nums) {int n nums.size();int res INT32_MAX;for (int i 1; i < n; i)for (int j i 1; j < n; j)res min(res, n…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(十三)

地址簿相关功能 1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.2 代码实现1.2.1 Mapper层1.2.2 Service层1.2.3 Controller层 1.1 需求分析和设计 1.1.1 产品原型 地址簿&#xff0c;指的是消费者用户的地址信息&#xff0c;用户登录成功后可以维护自己的地…

C#调用C动态链接库

前言 已经没写过博客好久了&#xff0c;上一篇还是1年半前写的LTE Gold序列学习笔记&#xff0c;因为工作是做通信协议的&#xff0c;然后因为大学时没好好学习专业课&#xff0c;现在理论还不扎实&#xff0c;不敢瞎写&#xff1b; 因为工作原因&#xff0c;经常需要分析一些字…

如何使用xlwings库为Excel表格的单元格创建超链接----关于Python里xlwings库对Excel表格的操作(三十九)

这篇小笔记主要记录【如何使用xlwings库为Excel表格的单元格创建超链接】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库&#xff1b; &#xff08;2&…

雷盛红酒LEESON分享葡萄酒也有“社会责任感”?

葡萄酒文化从来都不仅仅是感官体验&#xff0c;一瓶佳酿的背后不但蕴含着风土人情、历史传承和文化交流&#xff0c;更反映了时代社会的变迁以及体现的社会责任意识。 目前葡萄酒生产商追求酒瓶越来越轻就是葡萄酒市场上的一个趋势&#xff0c;因为任何一个行业都在追求与世界共…

坦克大战游戏代码

坦克大战游戏 主函数战场面板开始界面坦克父类敌方坦克我方坦克子弹爆炸效果数据存盘及恢复图片 主函数 package cn.wenxiao.release9;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JFrame; import javax.swing.JMenu; impor…

套接字通信(附带单线程TCP套接字通信代码)

套接字-Socket 1. 概念 1.1 局域网和广域网 局域网&#xff08;LAN&#xff09;和广域网&#xff08;WAN&#xff09;是两种不同范围的计算机网络&#xff0c;它们用于连接多台计算机以实现数据共享和通信。 局域网&#xff08;LAN&#xff09;&#xff1a; 定义&#xff1…

【JavaEE】文件操作与IO

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

0121-1-计算机网络安全

计算机网络安全 1.Get 和 Post 的区别 结构&#xff1a;get 有请求体&#xff0c;post没有请求体 应用场景&#xff1a;get 用于获取数据&#xff0c;post用于提交数据&#xff1b; 缓存&#xff1a;get 的缓存保存在浏览器和web服务器日志中&#xff1b; 传输方式&#x…