图解设计模式:动动手玩转迭代器模式

news2024/11/24 2:42:40

前言

📣 📣 📣 📢📢📢
☀️☀️点开就是缘分认识一下,我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。
📒 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️,擅长使用Java技术开发web项目和工具
📒 文章内容丰富:覆盖大部分java必学技术栈,前端,计算机基础,容器等方面的文章
📒 如果你也对Java感兴趣,关注小冷吧,一起探索Java技术的生态与进步,一起讨论Java技术的使用与学习
✏️高质量技术专栏专栏链接: 微服务数据结构netty,单点登录,SSMSpringCloudAlibaba
😝公众号😝想全栈的小冷,分享一些技术上的文章,以及解决问题的经验
当前专栏设计模式系列
专栏代码地址: 代码地址

动动手玩转迭代器模式(iterator)

​ 在Java语言中当我们需要查看数组的时候,我们最常见的方法就是使用循环预语句来遍历数组。

以for循环举例子

    for (int i = 0; i < arr.length; i++) {
      System.out.println(arr[i]);
    }

在for中 i++ 代表每次循环让 i 增加 来做到数组可以从前到后的遍历元素

将 i 抽象出来 形成通用化的模式 就是设计中的 迭代器模式

ps: 迭代器模式常用于 数组和集合遍历中

示例理解

我们用下图的书架来实现一个迭代器模式的示例 :

​ 示例程序的功能内容很简单就是我们将书架中书本的内容按照放入到顺序显示出来

image-20221214190242171

类与接口

image-20221214190414674

接口

迭代器接口 , 想要遍历某一个类这个类值具有两个条件

  • 实现了Aggregate接口 表示这个类可以被迭代器遍历
  • 有实现了Iterator 接口的适合本类型的迭代器器
public interface Iterator {

  public abstract boolean hasNext();

  public abstract Object next();
}
public interface  Aggregate {
    public abstract Iterator iterator();
}

Book 放 在书架上的书本类型

public class Book {

  private String Name;

  public Book(String name) {
    this.Name = name;
  }

  public String getName() {
    return  Name;
  }

}

书架

  • 放入书本
  • 查看书本(根据书本的index 来查找)
  • 获得书本数量
public class BookShelf implements Aggregate {

  private Book[] books;
  private int last = 0;

  public BookShelf(int maxsize) {
   this.books = new Book[maxsize];
  }

  public void appendBook(Book book) {
    this.books[last] = book;
    last++;
  }

  public int getLength() {
    return last;
  }

  public Iterator iterator(){
    return new BookShelfIterator(this);
  }

  public Book getBookAt(int index) {
      return books[index];
  }

用于查找书本的迭代器

  • 实现迭代器接口
  • 实现对书架的遍历
  • 实现拿出功能
public class BookShelfIterator implements Iterator {
  private BookShelf bookShelf;
  private int index;

  public BookShelfIterator(BookShelf bookShelf) {
    this.bookShelf = bookShelf;
  }

  @Override
  public boolean hasNext() {
    if(index<bookShelf.getLength()){
      return true;
    }else {
      return false;
    }
  }

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

示例测试

测试示例,简易的实现了对抽象循环i 来完成迭代书架展示书本内容

public class Test {

  public static void main(String[] args) {
    BookShelf bookShelf = new BookShelf(4);
    bookShelf.appendBook(new Book("A"));
    bookShelf.appendBook(new Book("B"));
    bookShelf.appendBook(new Book("C"));
    bookShelf.appendBook(new Book("D"));
    Iterator iterator = bookShelf.iterator();
    while (iterator.hasNext()){
      Book next = (Book) iterator.next();
      System.out.println(next.getName());
    }
  }
}

image-20221214191254711

迭代器中的角色

​ 在实现了简单的示例程序中 我们来回看一下迭代器中出现了哪几个角色

  • 迭代器 iterator 由它来定义一个迭代器规范
  • 具体的迭代器 Concretelterator :bookshlefiterator 基于迭代器规范实现了对书架的遍历
  • 集合 Aggrrgate 由它来定义一个创建迭代器的规范
  • 具体的集合 ConcreteAggregate :bookshelf基于Aggrrgate 规范实现了让这个类可以创建自己的迭代器

迭代器模式的类图

image-20221214191825395

拓展思路

为什么要用

​ Q : 为什么一定要考虑引入迭代器这样相对麻烦的设计模式呢?

​ Q : 如果只是数组 直接用循环来迭代不就可以吗 为什么要在集合之外引入迭代器这个角色呢?

​ A : 一个重要的理由 进入了迭代器之后 可以将遍历与实现分离开

代码片段

while (iterator.hasNext()){
  Book next = (Book) iterator.next();
  System.out.println(next.getName());
}

​ 这里知识使用率迭代器的 hasnext 和 next 方法,并没有调用 booskshelf 的方法 也就是说这里循环并不依赖 booskshelf 。

​ 那么如果假设 现在开发 booskshelf 的人员决定放弃数组来管理书本 而是选择用Java中的其他容器比如list vector取而代之呢,会如何? 不管 booskshelf 如何变化 只要 booskshelf 方法的 iterator 能正确的返回 iterator示例 即使不对上面的循环代码做任何的改动,代码也可以正常工作

​ 在没有迭代器模式的时候 人们总是用着实现好的类来直接操作 而不是定义一些抽象的规则 这也导致了代码复用性差,他们总是想用具体的类来解决所有的问题

Aggregate 与 iterator 对应

​ 我们在示例中 把booskshelfiterator定义为booskshelf 这个类的迭代器实现,也就是说 booskshelfiterator知道booskshelf 是如何实现的,也正是因为这个实现,我们可以获取下一本书的getBookAt方法。

​ 也就是说如果 booskshelf 发生改变 ,getBookAt这个方法也需要改变,改变的同时,我们也需要去修改

booskshelfiterator,正如Aggregate和iterator对应一样,实现的集合和迭代器也需要是对应的

拓展示例(改为arraylist来存放数据)

​ 只需要将书架类的数据操作方式稍作修改就可以实现替换存储结构,不需要去修改其他代码,操作代码的方式就变化了

public class BookShelf implements Aggregate {

  private ArrayList<Book> books;

  public BookShelf() {
   this.books = new ArrayList<>();
  }

  public void appendBook(Book book) {
    this.books.add(book);
  }

  public int getLength() {
    return books.size();
  }

  public Iterator iterator(){
    return new BookShelfIterator(this);
  }

  public Book getBookAt(int index) {
      return books.get(index);
  }

}

测试代码

  public static void main(String[] args) {
    BookShelf bookShelf = new BookShelf();
    bookShelf.appendBook(new Book("A"));
    bookShelf.appendBook(new Book("B"));
    bookShelf.appendBook(new Book("C"));
    bookShelf.appendBook(new Book("D"));
    Iterator iterator = bookShelf.iterator();
    while (iterator.hasNext()){
      Book next = (Book) iterator.next();
      System.out.println(next.getName());
    }
  }

image-20221214191254711

如果还想再通用一些可以使用泛型来将数据类型也变为可以传入的,过于简单所以提供一下思路即可

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

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

相关文章

JavaSE04

形参或者返回值是类名的话&#xff1a;方法的形参是类名&#xff0c;其实是需要的类名的对象。方法的返回值是类名的话&#xff0c;其实返回的是对象。 接口名 作为形参或者 方法的返回值&#xff1a;主要对应的是接口的实现类对象。 内部类的特点:内部类可直接访问外部类的成…

Unity中的C#脚本都继承了Monobehaviour类(Monobehaviour类的分析)

1、Monobehaviour类 Unity中的脚本都是继承Monobehaviour&#xff0c;定义了脚本的基本行为。必然是继承. 我们之前所熟知的声明周期函数。 除了必然事件&#xff0c;还定义了对各种特定事件的相应函数&#xff0c;均已On开头 MonoBehaviour中的事件响应函数都是已On开头的&am…

1 CPP11基础篇(快速学习)

另外还有 long double 不少于double 不低于double 注意&#xff1a; 在VS和Linux中 long double占用的内存空间分别是8和16个字节 c11原始字面量 void的关键字 在C中&#xff0c;void表示为无类型 主要有3个用途 1、函数的返回值用void 表示函数没有返回值 2、函数的参数填…

修改oracle11g的awr快照参数

1、select * from v$version; 2、select * from dba_hist_wr_control; 检查当前系统的保留时间为8天,1小时采样一次. 3、这里设置每半个小时收集一次&#xff0c; 收集到的数据保留15天&#xff0c;单位都是秒。 exec dbms_workload_repository.modify_snapshot_settings(ret…

[附源码]计算机毕业设计的图书互换系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

web前端网页设计期末课程大作业:旅游网页主题网站设计——三亚旅游网页设计(6个页面) HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

类装载器ClassLoader 、执行引擎ExecutionEngine【Java培训】

1. 定义 负责加载class文件&#xff0c;class文件在文件开头有特定的文件标示&#xff0c;并且ClassLoader只负责class文件的加载&#xff0c;至于它是否可以运行&#xff0c;则由Execution Engine决定。 Java培训 2. 类加载器分类 虚拟机自带的加载器启动类加载器&#xff0…

【现代机器人学】学习笔记六:闭链运动学

这一章的内容主要讲并联机器人的相关算法&#xff0c;内容在全书中属于比较少&#xff0c;仅仅介绍概念的章节。 恰好部门中有一位同事就是专门做并联机器人出身的博士&#xff0c;也请他帮忙看了一下内容&#xff0c;但他觉得写书的这个人可能也不是非常懂并联机器人&#xf…

Java集合——Collection

Collection集合 Collection接口下主要有三大子接口 List Queue Set 1. List List是有序可重复集合&#xff0c;根据索引下标来访问元素 List接口常见的三个实现类&#xff1a;ArrayList 、LinkedList、Vector 特点&#xff1a; 集合中的元素允许重复集合中的元素有序&…

UE4 Cook指定平台资源

内容烘焙 | 虚幻引擎文档 (unrealengine.com) 虚幻引擎以内部使用的特定格式存储内容资源&#xff0c;如PNG用于存储纹理 数据&#xff0c;WAV用于音频数据。但是&#xff0c;该内容需要针对各平台转换为不同的格式&#xff0c; 因为平台使用专有格式&#xff0c;或者平台不支…

Revit中“幕墙网格”编辑斜向网格和柱断墙梁

一、Revit中“幕墙网格”编辑斜向网格 我们可以为幕墙添加任意间距的水平和垂直的网格线&#xff0c;但是对于斜向网格线我们却只能通过设置其实例属性中的角度来控制其生成一系列等间距的斜向网格&#xff0c;那么如果遇到不等间距的斜向网格线我们应该如何绘制呢? 首先通过设…

博宜OJ练习题基础题目中个别问题的题(欢迎一起讨论)

中国博宜练习题个别问题&#xff0c;望讨论前言题目1解题思路提交后正确代码&#xff1a;个人写的错误代码题目2正确代码2个人写的错误代码2以上是个人目前遇到的两个问题&#xff0c;不知道是直接使用“max”函数的问题 还是什么&#xff0c;如果是“max”函数问题第一个测试点…

多线程与高并发(二)

【锁的底层实现】&#xff1a; 【 简介 】&#xff1a; JDK早期的时候是重量级的 &#xff0c; 会去找OS系统申请锁 &#xff0c;效率非常低。 后来的改进——《锁升级过程》。 【锁升级过程】&#xff1a; sync( Object ) 【偏向锁】&#xff1a; markword记录这个线程ID&…

[附源码]Python计算机毕业设计Django基于JEE平台springbt技术的订餐系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

以太网 MSTP多实例生成树的简介、MSTP与RSTP、STP之间的联系、MSTP BPDU格式介绍、MSTP关键名词介绍)

2.12.0 以太网 MSTP多实例生成树&#xff08;简介、MSTP与RSTP、STP联系、MSTP BPDU格式、MSTP关键名词介绍&#xff09; 主要参考&#xff1a;华为S2750, S5700, S6700 V200R005(C00&C01&C02&C03) 产品文档 《MSTP基本概念》 MSTP快速生成树简介MSTP关键名词介绍1…

springboot+mybatis+mysql实现的个人博客管理系统(功能包含登录,栏目管理、文章管理、评论管理、系统设置、用户管理、发布博客、评论等)

博客目录springbootmybatis实现的个人博客管理系统实现功能截图系统功能使用技术代码完整源码springbootmybatis实现的个人博客管理系统 本系统是一个个人博客管理系统&#xff0c;比较新的框架springbootmybatis实现&#xff0c;分为普通用户和管理员&#xff0c;普通用户可以…

【软件测试】测试人接手新应用程序怎么测?看看这几个方法......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 应用程序很复杂的&a…

三、数据链路层(三)差错控制

目录 3.1检错编码 3.1.1奇偶校验码 3.1.2循环冗余码&#xff08;CRC&#xff09; 3.2纠错编码 3.2.1海明码 传输差错可分为两种&#xff1a; 位错&#xff1a;帧中某些位出现了差错&#xff0c;也称比特差错、误码。帧错&#xff1a;帧的丢失、重复或失序等错误。 通常利…

面试题:数据结构和算法

1、时间复杂度解释一下 算法的时间复杂度&#xff0c;用来度量算法的运行时间&#xff0c;记作: T(n) O(f(n))。它表示随着 输入大小n 的增大&#xff0c;算法执行需要的时间的增长速度可以用 f(n) 来描述。 当 T(n) c&#xff0c;c 为一个常数的时候&#xff0c;我们说这个…

[附源码]Python计算机毕业设计Django基于vue+mysql开发的考试系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…