深入探索迭代器模式的原理与应用

🎯 设计模式专栏,持续更新中
欢迎订阅:JAVA实现设计模式
🛠️ 希望小伙伴们一键三连,有问题私信都会回复,或者在评论区直接发言

迭代器模式

💻 迭代器模式 (Iterator Pattern) 是一种行为设计模式,它允许你顺序访问一个集合对象中的元素,而无需暴露其底层表示。在不同的数据结构中,如数组、链表或其他集合,它可以统一提供一种方式来逐个遍历这些元素。

主要组成部分和UML类图

  1. Iterator 接口:定义遍历元素所需要的操作,如 hasNext()next().
  2. ConcreteIterator 具体迭代器:实现 Iterator 接口,负责具体遍历操作。
  3. Aggregate 聚合接口:提供创建迭代器的方法 createIterator().
  4. ConcreteAggregate 具体聚合类:实现聚合接口,包含实际元素集合,并返回迭代器实例。

在这里插入图片描述

生动案例理解:图书馆书架

情景:你走进图书馆,看到有许多不同的书架,每个书架有一排书。你想要逐一遍历每本书,但图书馆有不同种类的书架,它们的排列规则不同。使用迭代器模式,你可以通过同一个接口来遍历所有的书架,而无需关心每个书架的具体实现。

代码实现迭代器模式

让我们实现一个书架例子。书架有不同的书,通过迭代器,我们可以按顺序遍历这些书。

Step 1:定义书的类

lass Book {private String name;public Book(String name) {this.name = name;}public String getName() {return name;}
}

作用: 定义书的属性和构造函数,通过getName()方法可以获取书名。

Step 2:创建迭代器接口

interface BookIterator extends Iterator<Book> {boolean hasNext();Book next();
}

作用: 定义迭代器的接口,提供了hasNext()next()方法,用于遍历书籍。

Step 3: 具体的迭代器实现

// 第三步:具体迭代器实现类
class ShelfIterator implements BookIterator {private List<Book> books;private int position = 0;public ShelfIterator(List<Book> books) {this.books = books;}@Overridepublic boolean hasNext() {return position < books.size();}@Overridepublic Book next() {return books.get(position++);}
}

作用: ShelfIterator是迭代器的具体实现类,内部维护了当前遍历的位置并提供具体的遍历实现

Step 4: 定义聚合接口

// 第四步:抽象聚合接口
interface BookShelf {BookIterator createIterator();
}

作用: 定义了一个抽象聚合接口,用于创建一个新的迭代器。

Step 5: 实现具体聚合类

// 第五步:具体聚合实现类
class LibraryShelf implements BookShelf {private List<Book> books;public LibraryShelf() {this.books = new ArrayList<>();}public void addBook(Book book) {this.books.add(book);}@Overridepublic BookIterator createIterator() {return new ShelfIterator(books);}
}

作用: LibraryShelf是具体的聚合类,管理书籍的集合,并提供创建迭代器的方法。

Step 6: 测试类

// 第六步:测试类
public class Main {public static void main(String[] args) {LibraryShelf shelf = new LibraryShelf();shelf.addBook(new Book("Effective Java"));shelf.addBook(new Book("Design Patterns"));shelf.addBook(new Book("Clean Code"));BookIterator iterator = shelf.createIterator();System.out.println("Traversing the book shelf:");while (iterator.hasNext()) {Book book = iterator.next();System.out.println("Book: " + book.getName());}}
}

输出结果

Traversing the book shelf:
Book: Effective Java
Book: Design Patterns
Book: Clean Code

通过这个案例,你可以看到迭代器模式如何解耦聚合对象和遍历逻辑,使得可以以统一的方式遍历不同的集合。

JDK源码中的应用

在JDK中,迭代器模式广泛用于Collection框架,特别是在ListSetMap等数据结构中。让我们看看几个常见的示例:

java.util.Iterator

public interface Iterator<E> {boolean hasNext();E next();default void remove() {throw new UnsupportedOperationException("remove");}
}

应用: Iterator接口是Java集合框架中的迭代器标准接口。几乎所有的集合类(ArrayList, HashSet, LinkedList)都实现了这个接口,用于提供遍历方法。

java.util.ArrayList 的迭代器实现

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// ArrayList中的内部类实现了Iteratorprivate class Itr implements Iterator<E> {int cursor;       // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchpublic boolean hasNext() {return cursor != size();}public E next() {int i = cursor;if (i >= size)throw new NoSuchElementException();cursor = i + 1;return (E) elementData[lastRet = i];}public void remove() {// 删除操作}}public Iterator<E> iterator() {return new Itr();}
}

应用场景: ArrayListiterator() 方法返回的是内部类 Itr 的实例,Itr 实现了 Iterator 接口,通过 hasNext()next() 方法来遍历 ArrayList 中的元素。

迭代器模式总结

优点🟢

  1. 解耦集合与遍历:可以在不暴露集合内部表示的前提下遍历集合。
  2. 统一遍历接口:无论集合的类型或内部实现如何,迭代器提供了一致的遍历接口。
  3. 开闭原则:可以很容易地在不修改集合类的情况下扩展新类型的迭代器。
  4. 单一职责:将遍历逻辑从集合类中分离出来,简化了集合类的职责。

缺点 🔴

  1. 性能开销:迭代器模式通常需要额外的类来实现,可能会导致开销增加,尤其是对于大量的小型对象。
  2. 复杂性增加:对简单的数据结构来说,使用迭代器模式可能会使代码更加复杂。

适用场景

  • 遍历复杂数据结构:如树、图、链表等。迭代器可以隐藏这些数据结构的复杂性。
  • 需要统一遍历接口的地方:例如在一个框架或库中,不同的数据结构都需要通过相同的接口遍历。
  • 需要多种遍历方式:如从前到后、从后到前等,迭代器可以轻松扩展不同的遍历方式。

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

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

相关文章

saltstack高级用法

一、saltstack的高级用法 一、job管理 1、job简介 Jid&#xff1a;job id&#xff0c;格式为%Y%m%d%H%M%S%fmaster在下发指令消息时&#xff0c;会附带上产生的Jid&#xff0c;minion在接收到指令开始执行时&#xff0c;会在本地的cachedir&#xff08;默认是/var/cache/salt/…

力扣 2824.统计和小于目标的下标对数目

文章目录 题目介绍解法 题目介绍 解法 题目相当于从数组中选两个数&#xff0c;我们只关心这两个数的和是否小于 target&#xff0c;由于 abba&#xff0c;无论如何排列数组元素&#xff0c;都不会影响加法的结果&#xff0c;所以排序不影响结果的数量。 排序后&#xff1a; …

CDH Hive集群的create/drop慢问题,在200s 多一点处理分析

现象&#xff1a; CREATE TABLE test911 (SN String,PN_CODE String); Total time spent in this metastore function was greater than 1000ms : createTable_(Table, )200091 Hive集群的 create/drop 操作时间基本都稳定在 200s 多一点。 分析&#xff1a; HMS会实时向Sentr…

实战OpenCV之图像阈值处理

基础入门 图像阈值处理是一种二值化技术&#xff0c;它基于预设的阈值&#xff0c;可以将图像中的像素分为两大类&#xff1a;一大类是背景&#xff0c;另一大类是前景或目标对象。这个过程涉及将图像中的每个像素值与阈值进行比较&#xff0c;并根据比较结果决定保留原始值还是…

jmeter得到的文档数据处理

通过前面jmeter得到的输出文档&#xff0c;这里是txt文档&#xff0c;里面包含了很多条数据&#xff0c;每条数据的结构如下&#xff1a; 【request】 uuid&#xff1a;xxxxxxx timestamp&#xff1a;xxxxxxxx No.x question&#xff1a;xxxxxxx 【response】 code&#…

防火墙配置变更管理

在任何组织中&#xff0c;当涉及到网络安全时&#xff0c;频繁地更换防火墙是必要的&#xff0c;实施简化的防火墙更改管理策略模板可以减少管理时间&#xff0c;还可以减少每次变更引入新的安全性或合规性问题的可能性。典型的防火墙变更管理流程将包括以下步骤&#xff1a; …

排序----插入排序

一开始把第一个元素看成是有序的&#xff0c;然后从第二个元素开始拿出来与前面的数据比较&#xff0c;若前面的数据小&#xff0c;就把前面的数据不断后移&#xff08;注意要把拿出来的那个元素提前保存下来&#xff09;&#xff0c;直到遇到比自己小的元素&#xff0c;然后插…

大语言模型-教育方向数据集

大语言模型-教育方向数据集 编号论文数据集1Bitew S K, Hadifar A, Sterckx L, et al. Learning to Reuse Distractors to Support Multiple-Choice Question Generation in Education[J]. IEEE Transactions on Learning Technologies, 2022, 17: 375-390.Televic, NL, https…

Java 每日一刊(第12期):面向对象

“任何复杂的程序&#xff0c;都可以通过分解成若干个简单的问题来解决。” 前言 这里是分享 Java 相关内容的专刊&#xff0c;每日一更。 本期将为大家带来以下内容&#xff1a; 类对象类与对象的关系Java 中的三种变量类型OOP 的三大特性 类 类 是对现实世界中某类事物…

AntFlow系列教程之流程拒绝

这是开源项目AntFlow的一个系统入门使用教程.AntFlow是一款开源免费的企业级低代码工作流引擎.仿照钉钉设计,极大降低流程设计、开发和维护成本。详细介绍请查看历史文章&#xff1a;AntFlow开源仿钉钉低代码工作流平台集成RuoYi版本来啦 流程拒绝和流程同意提交的参数是一样的…

基于milvus数据库的RAG-Demo

1.上传文本并将文本向量化 import os from django.conf import settings from langchain.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter, CharacterTextSplitter from langchain.vectorstores import Chroma from l…

【JAVA入门】Day47 - 线程

【JAVA入门】Day47 - 线程 文章目录 【JAVA入门】Day47 - 线程一、并发和并行二、多线程的实现方式2.1 继承 Thread 类的方式2.2 实现 Runnable 接口的方式2.3 利用 Callable 接口实现 三、Thread 类中常见的成员方法四、线程的调度和优先级4.1 抢占式调度4.2 优先级4.3 守护线…

如何不终止容器退出Docker Bash会话

如何不终止容器退出Docker Bash会话 💖The Begin💖点点关注,收藏不迷路💖 当通过docker exec进入Docker容器的bash会话后,如果想退出但不停止容器,可以使用快捷键组合: 按下Ctrl+P然后紧接着按下Ctrl+Q。 这个操作会让你从bash会话中“分离”出来,但容器会继续运行…

Zabbix 部署----安装 Zabbix(监控服务器)

目录 zabbix 官网: 1、准备一台虚拟机 1.整理配置yum源(192.xx.xx.10) 2.设置主机名(192.xx.xx.10) 3.防火墙 4.selinux 2、准备Zabbix-repo 使用阿里提供的zabbixYUM源 3、安装Zabbix服务器 4、初始化数据库 1.安装数据库 2.启动数据库 3.授权zabbix账号 4.初始化…

解决使用nvm ls命令没有出现*的问题

一、引言 在输命令的时候不知道手误写了什么导致node命令用不了&#xff0c;查看环境变量配的nvm对应的路径没问题&#xff0c;试过网上说的修改文件夹名字但是没有用&#xff01;&#xff01; 输入 nvm ls 显示已下载的node版本&#xff0c;发现前面没有* 输入nvm use 使用其中…

【macOS】【zsh报错】zsh: command not found: python

【macOS】【zsh Error】zsh: command not found: python 本地已经安装了Python&#xff0c;且能在Pycharm中编译Python程序并运行。 但是&#xff0c;在macOS终端&#xff0c;运行Python&#xff0c;报错。 首先要确认你在macOS系统下&#xff0c;是否安装了Python。 如果安…

去噪扩散隐式模型

dataset_name "datasets/oxford-102-flowers/" dataset_repetitions 2 # 数据集重复 num_epochs 25 image_size 64 # 模型训练和生成图像的大小 # KID 内核初始距离 kid_image_size 75 # 从噪声中逐步“去噪”或“扩散”到最终图像所需的步骤数。 kid_diffusi…

NEMESIS: NORMALIZING THE SOFT-PROMPT VECTORS OF VISION-LANGUAGE MODELS

文章汇总 发现的现象 动机的描述 Norm增加会导致性能下降&#xff0c;Norm降低会导致性能上升。于是作者提出&#xff1a; 我们需要规范化VLMs中的软提示吗? 实验验证 在左图中的紫色块中可以看到&#xff0c;随着模型性能的上升&#xff0c;Norm value会不断下降。 解决…

C语言 | Leetcode C语言题解之第419题棋盘上的战舰

题目&#xff1a; 题解&#xff1a; int countBattleships(char** board, int boardSize, int* boardColSize){int row boardSize;int col boardColSize[0];int ans 0;for (int i 0; i < row; i) {for (int j 0; j < col; j) {if (board[i][j] X) {if (i > 0 &…

ant vue3 datePicker默认显示英文

改前&#xff1a; 改后&#xff1a; 处理方法&#xff1a; 在App.vue页加上以下导入即可 import dayjs from dayjs; import dayjs/locale/zh-cn dayjs.locale(zh-cn); 如图&#xff1a;