行为型设计模式——迭代器模式

news2024/11/15 2:09:17

迭代器模式

迭代器模式也是非常的简单,定义如下: 提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 相信大家都使用过类似下面的迭代器:

List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator(); //list.iterator()方法返回的肯定是Iterator接口的子实现类对象
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

如果在你的项目中需要对一个自定义的集合进行迭代遍历,那么迭代器模式是非常需要学习的。迭代器模式主要包含以下角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。

  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。

  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

案例实现

【例】定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现,涉及到的类如下:
在这里插入图片描述

代码如下

首先定义Student对象,如下:

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

然后定义Student类迭代器接口,主要就判断是否还有下一个元素和获取下一个元素两个方法,如下:

public interface StudentIterator {
    boolean hasNext();
    Student next();
}

然后实现学生类迭代器接口就好,如下:

public class StudentIteratoirImpl implements StudentIterator{
    private List<Student> list;
    private int position = 0;

    public StudentIteratoirImpl(List<Student> list){
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position<list.size();
    }

    @Override
    public Student next() {
        Student student = list.get(position);
        position++;
        return student;
    }
}

其实到这里我们就已经完成了迭代器功能了,可以使用下面的代码测试迭代器,如下:

public class Main {
    public static void main(String[] args) {

        // 测试迭代器类
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("张三",17));
        students.add(new Student("李四",19));
        students.add(new Student("王五",18));

        StudentIteratoirImpl iter = new StudentIteratoirImpl(students);
        while (iter.hasNext()){
            Student s = iter.next();
            System.out.println(s);
        }
    }
}

但是我们定义的是Student迭代器模型,上面的迭代器仅仅是实现了基础功能,如何需要的话我们可以将添加学生对象和删除学生对象的以及迭代的功能封装到一个容器类中,当然这部分内容属于扩展内容,如下:

// 定义学生容器接口
public interface StudentContainer {
    // 添加学生的操作
    void addStudent(Student student);
    // 移除学生
    void removeStudent(Student student);
    // 获取学生迭代器
    StudentIterator getStudentIterator();
}

// 实现学生容器接口
public class StudentContainerImpl implements StudentContainer{
    private List<Student> list = new ArrayList<Student>();
    @Override
    public void addStudent(Student student) {
        list.add(student);
    }

    @Override
    public void removeStudent(Student student) {
        list.remove(student);
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratoirImpl(list);
    }
}

客户类测试:

public class Main {
    public static void main(String[] args) {

        // 测试迭代器类
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("张三",17));
        students.add(new Student("李四",19));
        students.add(new Student("王五",18));

        StudentIteratoirImpl iter = new StudentIteratoirImpl(students);
        while (iter.hasNext()){
            Student s = iter.next();
            System.out.println(s);
        }

        System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");

        // 测试学生容器类
        StudentContainerImpl studentContainer = new StudentContainerImpl();
        studentContainer.addStudent(new Student("张三",17));
        studentContainer.addStudent(new Student("李四",19));
        studentContainer.addStudent(new Student("王五",18));
        StudentIterator studentIterator = studentContainer.getStudentIterator();
        while (studentIterator.hasNext()){
            Student s = studentIterator.next();
            System.out.println(s);
        }
    }
}

输出结果:

Student{name=‘张三’, age=17}
Student{name=‘李四’, age=19}
Student{name=‘王五’, age=18}
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Student{name=‘张三’, age=17}
Student{name=‘李四’, age=19}
Student{name=‘王五’, age=18}

优点

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

缺点

增加了类的个数,这在一定程度上增加了系统的复杂性。

使用场景

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

参考内容:

传智播客设计模式相关笔记(主要)

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

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

相关文章

Seata TC端协调全局事务

1、Seata server注册器 //来自RM分支事务注册 super.registerProcessor(MessageType.TYPE_BRANCH_REGISTER, onRequestProcessor, messageExecutor); //开启全局事务 super.registerProcessor(MessageType.TYPE_GLOBAL_BEGIN, onRequestProcessor, messageExecutor); //提交全…

MySQL夯实之路-事务详解

事务四大特性 事务需要通过严格的acid测试。Acid表示原子性&#xff0c;一致性&#xff0c;隔离性&#xff0c;持久性。 原子性&#xff08;atomicity&#xff09; 事务是不可分割的最小单元&#xff0c;对于整个事务的操作&#xff0c;要么全部提交成功&#xff0c;要么全部…

Linux———ps命令详解

目录 ps 命令&#xff08;"process status" 的缩写。&#xff09; 常用选项和参数&#xff1a; a&#xff1a;显示所有用户的进程&#xff0c;包括其他用户的进程。​ u&#xff1a;显示详细的进程信息&#xff0c;包括进程的所有者、CPU 使用率、内存使用量等。…

白嫖aws创建Joplin server服务器

网上有很多的Joplin服务器的搭建教程&#xff0c;但是基本都是抄来抄去&#xff0c;对初学者实在是太不友好了。 话不多说&#xff0c;说干就干&#xff0c;自己从头找资料搭了一个&#xff0c;这可能是全网最好的Joplin服务器搭建教程了。 aws服务器 aws的服务器还是很香的&…

MAVROS的进一步理解

一、Mavros简介 顾名思义&#xff0c; mavros就是mavlinkros。mavros是PX4官方提供的一个运行于ros下收发mavlink消息的工具&#xff0c;利用mavros可以发送mavlink消息给飞控(可以控制飞机)&#xff0c;并且可以从飞控中接受数据(例如&#xff1a;飞控的位置速度 IMU数据等等…

论文阅读_训练大模型用于角色扮演

英文名称: Character-LLM: A Trainable Agent for Role-Playing 中文名称: 角色-LLM&#xff1a;训练Agent用于角色扮演 文章: [https://arxiv.org/abs/2310.10158](https://arxiv.org/abs/2310.10158) 作者: Yunfan Shao, Linyang Li, Junqi Dai, Xipeng Qiu 机构: 复旦大学…

使用numpy处理图片——分离通道

大纲 读入图片分离通道堆叠法复制修改法 生成图片 在《使用numpy处理图片——滤镜》中&#xff0c;我们剥离了RGB中的一个颜色&#xff0c;达到一种滤镜的效果。 如果我们只保留一种元素&#xff0c;就可以做到PS中分离通道的效果。 读入图片 import numpy as np import PIL.…

【UE Niagara学习笔记】04 - 火焰喷射时的黑烟效果

目录 效果 步骤 一、创建烟雾材质 二、添加新的发射器 三、设置新发射器 3.1 删除Color模块 3.2 减少生成的粒子数量 3.3 设置粒子初始颜色 3.4 设置烟雾的位置偏移 3.5 设置烟雾淡出 在上一篇博客&#xff08;【UE Niagara学习笔记】03 - 火焰喷射效果&#xf…

【开源】基于JAVA+Vue+SpringBoot的医院门诊预约挂号系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2 科室医生档案模块2.1.3 预约挂号模块2.1.4 医院时政模块 2.2 可行性分析2.2.1 可靠性2.2.2 易用性2.2.3 维护性 三、数据库设计3.1 用户表3.2 科室档案表3.3 医生档案表3.4 医生放号…

5文件操作

包含头文件<fstream> 操作文件三大类&#xff1a; ofstream : 写文件ifstream &#xff1a;读文件fstream : 读写文件 5.1文本文件 -文件以ascii的形式存储在计算机中 5.1.1写文件 步骤&#xff1a; 包含头文件 #include "fstream"创建流对象 ofs…

【Linux运维】LVM和RAID学习及实践

LVM和RAID学习及实践 背景LVM简介新加硬盘的操作RAID-磁盘阵列应用场景RAID0RAID1其他结构RAID制作RAID 小结 背景 某台服务器的磁盘管理需要自己动手处理&#xff0c;找了一些资料也踩了一些坑&#xff0c;在这里记录一下&#xff0c;先介绍一下LVM和RAID这两个东西。在计算机…

Java实现在线编辑预览office文档

文章目录 1 在线编辑1.1 PageOffice简介1.2 前端项目1.2.1 配置1.2.2 页面部分 1.3 后端项目1.3.1 pom.xml1.3.2 添加配置1.3.3 controller 2 在线预览2.1 引言2.2 市面上现有的文件预览服务2.2.1 微软2.2.2 Google Drive查看器2.2.3 阿里云 IMM2.2.4 XDOC 文档预览2.2.5 Offic…

逆变器3前级推免(高频变压器)

一节电池标压是在2.8V—4.2V之间&#xff0c;所以24V电压需要大概七节电池串联。七节电池电压大概在19.6V—29.4V之间。 从24V的电池逆变到到220V需要升压的过程。那么我们具体需要升压到多少&#xff1f; 市电AC220V是有效值电压&#xff0c;峰值电压是220V*1.414311V 如果…

ubuntu安装node

1 下载 node 官网下载 如果需要其他版本&#xff0c;点击上图的Other Downloads 这里下载的版本是20.11.0 Linux Binaries (x64)&#xff0c;下载下来后是node-v20.11.0-linux-x64.tar.xz这样的格式&#xff0c;直接右键解压得到如下目录&#xff1a; 直接拷贝该文件夹到指定目…

一些前端学习过程的自测练习题

目录 页面设计部分 1 设计一个简单的学院网站首页&#xff1b; 2.按照图示要求完成简单的登录页面 3.完成如下网站设计 4.完成如下网站设计&#xff08;练习页面布局&#xff09; 5 利用下面素材&#xff0c;设计一个满足H5规范的网页&#xff08;移动端页面练习&#xff…

有道云笔记编辑 Markdown 文件 - GitHub README.md

有道云笔记编辑 Markdown 文件 - GitHub README.md 1. 新建 -> Markdown2. GitHub README.mdReferences 1. 新建 -> Markdown ​ 2. GitHub README.md ​​​ References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

group by 查询慢的话,如何优化?

1、说明 根据一定的规则&#xff0c;进行分组。 group by可能会慢在哪里&#xff1f;因为它既用到临时表&#xff0c;又默认用到排序。有时候还可能用到磁盘临时表。 如果执行过程中&#xff0c;会发现内存临时表大小到达了上限&#xff08;控制这个上限的参数就是tmp_table…

中通快递批量查询方法

你是否经常需要处理大量的中通快递单号&#xff0c;却苦于一个个等待查询&#xff1f;现在&#xff0c;有了固乔快递查询助手&#xff0c;这个问题迎刃而解&#xff01;通过批量查询功能&#xff0c;你可以轻松管理、追踪你的中通快递单号&#xff0c;大大提高工作效率。 一、下…

spark中Rdd依赖和SparkSQL介绍--学习笔记

1&#xff0c;RDD的依赖 1.1概念 rdd的特性之一 相邻rdd之间存在依赖关系&#xff08;因果关系&#xff09; 窄依赖 每个父RDD的一个Partition最多被子RDD的一个Partition所使用 父rdd和子rdd的分区是一对一&#xff08;多对一&#xff09; 触发窄依赖的算子 map()&…

提交代码,SVN被锁定,提示:svn is already locked解决方案

今天遇到一个问题&#xff0c;svn 在提交代码的时候出现了svn is already locked&#xff0c;解决方案如下图 点击clean up 点击ok即可 来看官方对clean up的解释&#xff1a;它的作用就是查找工作拷贝中的所有遗留的日志文件&#xff0c;删除进程中工作拷贝的锁。 参考&…