迭代器模式深度解析与实战案例
一、模式定义
迭代器模式(Iterator Pattern) 是一种行为设计模式,提供一种方法顺序访问聚合对象的元素,无需暴露其底层表示。核心思想是将遍历逻辑从聚合对象中分离,实现 遍历与存储的解耦。
二、核心组件
组件 | 作用 |
---|---|
Iterator | 定义遍历接口(hasNext/next) |
ConcreteIterator | 实现具体集合的遍历逻辑 |
Aggregate | 聚合对象接口,定义创建迭代器的方法 |
ConcreteAggregate | 具体聚合对象,实现迭代器创建方法 |
三、模式优势
统一遍历接口:不同集合使用相同方式遍历
单一职责原则:分离集合管理与遍历算法
开闭原则:新增迭代器类型不影响现有代码
并行遍历:支持多个迭代器同时遍历集合
四、真实场景案例:社交网络关系遍历
场景需求
某社交平台需要实现:
用户关系包含 好友列表(数组存储)和 关注列表(链表存储)
需要统一接口遍历两种关系
支持 隐私过滤(不展示已注销用户)
五、Java实现代码
1. 迭代器接口
public interface RelationIterator<T> {boolean hasNext();T next();void remove();
}
2. 聚合对象接口
public interface SocialNetwork {RelationIterator<User> createIterator();RelationIterator<User> createActiveUserIterator(); // 扩展:过滤非活跃用户
}
3. 具体聚合对象实现
// 好友列表(数组存储)
class FriendList implements SocialNetwork {private User[] friends;private int size;public FriendList(int capacity) {friends = new User[capacity];}public void addFriend(User user) {if (size < friends.length) {friends[size++] = user;}}@Overridepublic RelationIterator<User> createIterator() {return new FriendListIterator();}@Overridepublic RelationIterator<User> createActiveUserIterator() {return new ActiveFriendListIterator();}// 具体迭代器实现(内部类)private class FriendListIterator implements RelationIterator<User> {private int position = 0;@Overridepublic boolean hasNext() {return position < size;}@Overridepublic User next() {if (!hasNext()) throw new NoSuchElementException();return friends[position++];}@Overridepublic void remove() {throw new UnsupportedOperationException();}}// 扩展:过滤非活跃用户private class ActiveFriendListIterator implements RelationIterator<User> {private int position = 0;@Overridepublic boolean hasNext() {skipInactiveUsers();return position < size;}@Overridepublic User next() {if (!hasNext()) throw new NoSuchElementException();return friends[position++];}private void skipInactiveUsers() {while (position < size && !friends[position].isActive()) {position++;}}}
}// 关注列表(链表存储)
class FollowingList implements SocialNetwork {private static class Node {User user;Node next;Node(User user) {this.user = user;}}private Node head;private Node tail;public void addFollowing(User user) {Node newNode = new Node(user);if (head == null) {head = tail = newNode;} else {tail.next = newNode;tail = newNode;}}@Overridepublic RelationIterator<User> createIterator() {return new FollowingListIterator();}// 具体迭代器实现(内部类)private class FollowingListIterator implements RelationIterator<User> {private Node current = head;@Overridepublic boolean hasNext() {return current != null;}@Overridepublic User next() {if (!hasNext()) throw new NoSuchElementException();User user = current.user;current = current.next;return user;}@Overridepublic void remove() {throw new UnsupportedOperationException();}}
}
4. 用户实体类
public class User {private final String id;private String name;private boolean active = true;public User(String id, String name) {this.id = id;this.name = name;}// Getters/Setterspublic boolean isActive() { return active; }public void deactivate() { active = false; }
}
5. 客户端使用
public class SocialNetworkClient {public static void main(String[] args) {// 初始化数据User user1 = new User("U001", "张三");User user2 = new User("U002", "李四");user2.deactivate();User user3 = new User("U003", "王五");// 构建好友列表FriendList friends = new FriendList(10);friends.addFriend(user1);friends.addFriend(user2);friends.addFriend(user3);// 构建关注列表FollowingList followings = new FollowingList();followings.addFollowing(user3);followings.addFollowing(user1);// 遍历好友列表(基础迭代器)System.out.println("=== 好友列表 ===");printRelations(friends.createIterator());// 遍历关注列表System.out.println("\n=== 关注列表 ===");printRelations(followings.createIterator());// 使用过滤迭代器System.out.println("\n=== 活跃好友 ===");printRelations(friends.createActiveUserIterator());}private static void printRelations(RelationIterator<User> iterator) {while (iterator.hasNext()) {User user = iterator.next();System.out.printf("%s (%s)%n", user.getName(), user.isActive() ? "活跃" : "已注销");}}
}
六、运行结果
=== 好友列表 ===
张三 (活跃)
李四 (已注销)
王五 (活跃)=== 关注列表 ===
王五 (活跃)
张三 (活跃)=== 活跃好友 ===
张三 (活跃)
王五 (活跃)
七、模式变体与优化
1. 多维度迭代
// 组合条件迭代器
public interface CompositeIterator<T> extends RelationIterator<T> {void addFilter(Predicate<T> filter);void sort(Comparator<T> comparator);
}// 使用示例
CompositeIterator<User> iterator = new SmartUserIterator();
iterator.addFilter(User::isVIP);
iterator.sort(Comparator.comparing(User::getJoinDate));
2. 线程安全实现
// 快照迭代器(避免ConcurrentModificationException)
public class SnapshotIterator<T> implements RelationIterator<T> {private final List<T> snapshot;private int position = 0;public SnapshotIterator(Collection<T> original) {this.snapshot = new ArrayList<>(original);}// 实现标准迭代器方法...
}
八、行业应用场景
场景 | 具体应用 | 优势体现 |
---|---|---|
文件系统遍历 | 递归遍历目录结构 | 统一处理文件/文件夹 |
数据库查询 | 结果集游标遍历 | 处理海量数据内存优化 |
游戏物品系统 | 背包不同分类物品遍历 | 支持多种筛选条件 |
大数据处理 | 分片数据顺序访问 | 处理超出内存限制的数据 |
GUI组件树遍历 | 窗口组件层级遍历 | 支持深度优先/广度优先策略 |
九、最佳实践建议
迭代器生命周期管理
// 使用try-with-resources管理资源
try (RelationIterator<User> iterator = friends.createIterator()) {while (iterator.hasNext()) {// 处理逻辑}
}
空迭代器实现
// 空对象模式应用
public class EmptyIterator<T> implements RelationIterator<T> {@Override public boolean hasNext() { return false; }@Override public T next() { throw new NoSuchElementException(); }
}
性能优化技巧
// 预计算迭代路径(适用于树形结构)
public class PrecomputedTreeIterator<T> implements RelationIterator<T> {private final List<T> traversalPath;private int index = 0;public PrecomputedTreeIterator(TreeNode root) {this.traversalPath = preorderTraversal(root);}// 实现标准方法...
}
十、与相似模式对比
模式 | 核心差异 | 适用场景 |
---|---|---|
迭代器 | 专注集合遍历机制 | 需要统一遍历接口的场景 |
访问者 | 在遍历过程中执行操作 | 对集合元素进行复杂操作 |
组合 | 处理树形结构 | 需要递归遍历的层级结构 |
工厂方法 | 用于创建迭代器对象 | 需要灵活创建不同类型迭代器 |
通过这个社交网络关系遍历的案例,可以看出迭代器模式如何 有效封装不同数据结构的遍历逻辑。在实际开发中,可根据需求扩展迭代器功能(如过滤、排序、分页等),同时保持客户端代码的简洁性。该模式特别适合需要支持多种数据存储方式且需要统一访问接口的系统架构。
一句话总结
迭代器模式是为了提供一种能顺序遍历对象的解决方案,该方案不对外暴露存储细节。
相关文章:
迭代器模式深度解析与实战案例
一、模式定义 迭代器模式(Iterator Pattern) 是一种行为设计模式,提供一种方法顺序访问聚合对象的元素,无需暴露其底层表示。核心思想是将遍历逻辑从聚合对象中分离,实现 遍历与存储的解耦。 二、核心组件 组件作用…...
Kotlin协程实用模版合集
目录 ✅ Kotlin 协程实用模板合集(适合 Android 项目) 📦 1. 基础挂起函数封装(Repository 层) ⚙️ 2. ViewModel 中使用协程 状态处理 ⏱️ 3. 带超时控制的挂起操作 🤝 4. 并发请求合并࿰…...
基于Flask的Windows事件ID查询系统开发实践
基于Flask的Windows事件ID查询系统开发实践 一、项目背景与功能概述 Windows操作系统的事件日志系统记录了数百种不同的事件ID,每个ID对应特定的系统事件。本文介绍如何构建一个基于Web的事件ID查询系统,主要实现以下功能: 数据可视化展示…...
机器人编程基础---C语言中的运算符
C语言中的运算符 算术运算符关系运算符逻辑运算符位运算符C语言提供了多种运算符来执行不同的操作。 算术运算符 + 加法- 减法* 乘法/ 除法% 取模(求余)++ 自增-- 自减int a = 10, b = 5; int sum = a + b;...
设计模式之迭代器模式:遍历的艺术与实现
引言 迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种顺序访问聚合对象中各个元素的方法,而又不暴露其底层实现。迭代器模式将遍历逻辑与聚合对象解耦,使得我们可以用统一的方式处理不同的集合结构。…...
React七案例中
代码下载 地图找房模块 顶部导航栏 封装NavHeader组件实现城市选择,地图找房页面的复用,在 components 目录中创建组件 NavHeader,把之前城市列表写过的样式复制到 NavHeader.scss 下,在该组件中封装 antd-mobile 组件库中的 N…...
消息中间件篇——RabbitMQ,Kafka
RabbitMQ 如何保证消息不丢失? 生产者确认机制 消息持久化 消费者确认机制 RabbitMQ如何保证消息不丢失? RabbitMQ的重复消费问题如何解决? RabbitMQ中死信交换机(RabbitMQ延迟队列有了解过吗?) 延迟队列…...
HOW - 实现 useClickOutside 或者 useClickAway
场景 在开发过程中经常遇到需要点击除某div范围之外的区域触发回调:比如点击 dialog 外部区域关闭。 手动实现 import { useEffect } from "react"/*** A custom hook to detect clicks outside a specified element.* param ref - A React ref object…...
青少年编程考试 CCF GESP Python七级认证真题 2025年3月
Python 七级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 B C A B B A A B C A B B A B A 1 单选题(每题 2 分,共 30 分) 第 1 题 下列哪个选项是python中的关键字? A. function B. class C. method D. object…...
兆讯MH2103系列pin to pin替代STM32F103,并且性能超越
MH2103 是一款高性能的 32 位微控制器,由兆讯恒达推出,主要用于替代 STM32F103 系列产品。以下是关于 MH2103 芯片的详细介绍: 技术规格 内核与主频: 采用高性能 32 位 Cortex-M3 内核,最高工作频率可达 216 MHz。支…...
h5使用dsBridge与原生app通信--桥方法
dsBridge是一个轻量级的 JS 和原生 App 的通信桥梁库,使用起来比原生方便不少支持: 1.H5 调用 Native 方法(JS → Native) 2.Native 调用 H5 方法(Native → JS) 3.支持参数传递和异步回调 4.支持 Android、iOS、以…...
package.json配置项积累
peerDependencies 用途:peerDependencies 主要用于声明一个包在其宿主项目中期望安装的依赖版本。它通常用于确保插件或库与特定版本的其他库兼容。 行为: 在 npm v7之前,如果宿主项目未安装 peerDependencies 中列出的依赖,则不…...
Python安装软件包报错 fatal error: Python.h: No such file or directory
Python安装软件包报错 fatal error: Python.h: No such file or directory Failed to import transformers.integrations.integration_utils because of the following error (look up to see its traceback): Failed to import transformers.modeling_utils because of the f…...
数据结构与算法-图论-复习1(单源最短路,全源最短路,最小生成树)
1. 单源最短路 单一边权 BFS 原理:由于边权为单一值,可使用广度优先搜索(BFS)来求解最短路。BFS 会逐层扩展节点,由于边权相同,第一次到达某个节点时的路径长度就是最短路径长度。 用法:适用…...
uniapp:微信小程序,一键获取手机号
<button open-type"getPhoneNumber" getphonenumber"getphonenumber">一键获取</button> <script>export default {methods: {getphonenumber(e){uni.login({provider: weixin,success: (res)> {console.log(res);},});},}} </scr…...
协作焊接机器人
一、核心定义与核心特点 1. 定义 协作焊接机器人是基于协作机器人本体(具备力传感、轻量化、安全停机等特性),集成焊接电源、焊枪、视觉 / 电弧传感器等模块,实现人机共融焊接作业的自动化设备。其核心在于: 安全协作:支持与焊工共同工作,无需物理隔离;柔性适配:快速…...
SpringBoot和微服务学习记录Day2
微服务 微服务将单体应用分割成更小的的独立服务,部署在不同的服务器上。服务间的关联通过暴露的api接口来实现 优点:高内聚低耦合,一个模块有问题不影响整个应用,增加可靠性,更新技术方便 缺点:增加运维…...
【CornerTag组件详解:优雅的角标设计与实现】
CornerTag组件详解:优雅的角标设计与实现 组件完整代码 <template><divclass"corner-tag":style"{background: bgColor,padding: ${paddingY}px 0,fontSize: fontSize px,...customStyle}"><slot /></div> </tem…...
Mybatis-缓存详解
什么是缓存? 存在内存中的临时数据 将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题 经…...
WHAT - React useId vs uuid
目录 uuiduseId适用场景语法示例注意事项 复杂示例示例:动态表单列表 useId解读重点 useId vs uuid一句话总结对比表格示例对比useId 用于表单uuid() 用在 UI 会出问题uuid 的适合场景 总结建议 uuid 在 WHAT - Math.random?伪随机? 中我们…...
Leetcode 跳跃游戏 II (贪心算法)
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…...
银河麒麟V10 Ollama+ShellGPT打造Shell AI助手——筑梦之路
环境说明 1. 操作系统版本: 银河麒麟V10 2. CPU架构:X86 3. Python版本:3.12.9 4. 大模型:mistral:7b-instruct 准备工作 1. 编译安装python 3.12 # 下载python 源码wget https://www.python.org/ftp/python/3.12.9/Python-3.12.9.tg…...
【物联网】GPT延时
文章目录 前言一、GPT实现延时1. 定时器介绍2. I.MX6ull GPT定时器介绍1)GPT定时器工作原理2)GPT的输入捕获3)GPT的输出比较 3. 高精度延时实现1)实现思路 前言 使用 GPT 实现延时控制以及基于 PWM 实现蜂鸣器发声与频率调节这两…...
【套题】大沥2019年真题——第4题
04.数字圈 题目描述 当我们写数字时会发现有些数字有封闭区域,有的数字没有封闭区域。 数字 0 有一个封闭区域,数字 1、2、 3 都没有封闭区域,数字 4 有一个封闭区域,数字 5 没有封闭区域,数字 6 有一个封闭区域&#…...
idea 安装 proxyai 后的使用方法
1. 可以默认使用ProxyAi 安装后使用如下配置可以进行代码提示 配置 使用示例 2. 这里有必要说一下,这里要选择提供服务的ai 选择后才可以使用ProxyAI或者Custom openAI 3. 可以使用custom openAi, 要自行配置 1)配置 code completions 这是header …...
构建实时、融合的湖仓一体数据分析平台:基于 Delta Lake 与 Apache Iceberg
1. 执行摘要 挑战: 传统数据仓库在处理现代数据需求时面临诸多限制,包括高昂的存储和计算成本、处理海量多样化数据的能力不足、以及数据从产生到可供分析的端到端延迟过高。同时,虽然数据湖提供了低成本、灵活的存储,但往往缺乏…...
数据库的MVCC机制详解
MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库系统中常用的并发控制机制,它允许数据库在同一时间点保存数据的多个版本,从而实现非阻塞的读操作,提高并发性能。 MVCC的核心思想是&…...
未来与自然的交响:蓉城生态诗篇
故事背景 故事发生在中国四川成都,描绘了未来城市中科技与自然共生的奇迹。通过六个极具创意的生态场景,展现人类如何以诗意的方式重构与自然的连接,在竹海保育、文化传承、能源循环等维度编织出震撼心灵的未来图景。 故事内容 当晨雾在竹纤维…...
【愚公系列】《高效使用DeepSeek》062-图书库存管理
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
汽车软件开发常用的建模工具汇总
目录 往期推荐 1.Enterprise Architect(EA) 2.MATLAB/Simulink 3.TargetLink 4.Rational Rhapsody 5.AUTOSAR Builder 6.PREEvision 总结 往期推荐 2025汽车行业新宠:欧企都在用的工具软件ETAS工具链自动化实战指南<一&am…...
六、继承(二)
1 继承与友元 如果一个基类中存在友元关系,那么这个友元关系能不能继承呢? 例: #include <iostream> using namespace std; class Student; class Person { public:friend void Display(const Person& p, const Student& s)…...
flink部署使用(flink-connector-jdbc)连接达梦数据库并写入读取数据
flink介绍 1)Apache Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。Flink 被设计在所有常见的集群环境中运行,以内存执行速度和任意规模来执行计算。 2)在实时计算或离线任务中,往往需要…...
【Rust开发】Rust快速入门,开发出Rust的第一个Hello World
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
Flink框架:批处理和流式处理与有界数据和无界数据之间的关系
本文重点 从数据集的类型来看,数据集可以分为有界数据和无界数据两种,从处理方式来看,有批处理和流处理两种。一般而言有界数据常常使用批处理方式,无界数据往往使用流处理方式。 有界数据和无界数据 有界数据有一个明确的开始和…...
基于 Spring Boot 瑞吉外卖系统开发(四)
基于 Spring Boot 瑞吉外卖系统开发(四) 新增分类 新增分类UI界面,两个按钮分别对应两个UI界面 两个页面所需的接口都一样,请求参数type值不一样,type1为菜品分类,type2为套餐分类。 请求方法都为POST。…...
患者根据医生编号完成绑定和解绑接口
医疗系统接口文档 一、Controller 层 1. InstitutionDoctorController 医疗机构和医生相关的控制器,提供机构查询、医生查询、绑定解绑医生等功能。 RestController RequestMapping("/institution-doctor") public class InstitutionDoctorController…...
Flutter性能优化终极指南:从JIT到AOT的深度调优
一、Impeller渲染引擎调优策略 1.1 JIT预热智能预编译 // 配置Impeller预编译策略 void configureImpeller() {ImpellerEngine.precacheShaders(shaders: [lib/shaders/skinned_mesh.vert,lib/shaders/particle_system.frag],warmupFrames: 30, // 首屏渲染前预编译帧数cach…...
(1)英特尔 RealSense T265(三)
文章目录 前言 4.4 地面测试 4.5 飞行测试 4.6 室内外实验 4.7 数据闪存记录 4.8 启动时自动运行 4.9 使用 OpticalFlow 进行 EKF3 光源转换 前言 Realsense T265 通过 librealsense 支持 Windows 和 Linux 系统。不同系统的安装过程差异很大,因此请参阅 gi…...
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C 目录 前言 一、列表初始化 1. 大括号初始化 2. initializer_list 二、右值引用和移动语义 1. 左值和右值 2. 左值引用和右值引用 引用延长生命周期 左…...
ArcGIS 给大面内小面字段赋值
文章目录 引言:地理数据处理中的自动化赋值为何重要?实现思路模型实现关键点效果实现步骤1、准备数据2、执行3、完成4、效果引言:地理数据处理中的自动化赋值为何重要? 在地理信息系统(GIS)的日常工作中,空间数据的属性字段赋值是高频且关键的操作,例如在土地利用规划…...
计算机网络——传输层(Udp)
udp UDP(User Datagram Protocol,用户数据报协议 )是一种无连接的传输层协议,它在IP协议(互联网协议)之上工作,为应用程序提供了一种发送和接收数据报的基本方式。以下是UDP原理的详细解释&…...
【操作系统(Linux)】——生产者消费者同步互斥模型
✅ 一、程序功能概述 我们将做的:实现一个经典的「生产者-消费者问题」多线程同步模型的案例,主要用到 循环缓冲区 POSIX 信号量 sem_t pthread 多线程库,非常适合理解并发控制、线程通信和缓冲区管理。 案例目标:通过多个生产…...
从数据到洞察:探索数据分析与可视化的高级方法
从数据到洞察:探索数据分析与可视化的高级方法 引言 在今天这个数据驱动的时代,海量的数据只有通过科学分析和清晰可视化,才能转化为商业价值和决策依据。然而,数据分析与可视化远不只是制作几个图表,它需要高级技术、深度洞察力以及良好的工具支持。随着大数据领域的快…...
计算机视觉中的数学:几何变换与矩阵运算详解
计算机视觉中的数学:几何变换与矩阵运算详解 一、前言二、基础数学概念回顾2.1 向量与向量运算2.1.1 向量的定义2.1.2 向量运算 2.2 矩阵基础2.2.1 矩阵的定义与表示2.2.2 矩阵运算 三、几何变换基础3.1 平移变换3.1.1 原理3.1.2 代码示例&…...
华为数字芯片机考2025合集3已校正
1. 题目内容 下列说法正确的是()。 1. 解题步骤 1.1 选项分析 选项描述正误依据A异步 FIFO 采用格雷码是为了省功耗✗格雷码用于消除多比特信号跨时钟域的位跳变风险,与功耗无关B单比特信号打两拍可以完全避免亚稳态✗双触发器同步仅降低…...
启山智软的营销方法有哪些优势?
启山智软作为一家科技或软件企业,其营销方法的优势可能体现在以下几个方面,这些优势结合了行业特点与创新策略,帮助其在竞争激烈的市场中占据有利位置: 1. 技术驱动的精准营销 数据挖掘与AI应用: 通…...
openpyxl合并连续相同元素的单元格
文章目录 前言一、openpyxl是什么?二、基础用法1.读取和写入文件2.合并单元格 三、合并单元格实战1.连续相同元素的索引范围2.转换3.获取列合并索引4.整体 总结 前言 python可以很方便的操作各种文档,比如docx,xlsx等。本文主要介绍在xlsx文…...
从零开始学java--泛型(二)
泛型 目录 泛型 泛型与多态 泛型方法 泛型的界限 泛型与多态 不只是类,包括接口、抽象类都可以支持泛型: public static void main(String[] args) {Score<String> scorenew Score<>("数学","aa","优秀"…...
设计模式 Day 6:深入讲透观察者模式(真实场景 + 回调机制 + 高级理解)
观察者模式(Observer Pattern)是一种设计结构中最实用、最常见的行为模式之一。它的魅力不仅在于简洁的“一对多”事件推送能力,更在于它的解耦能力、模块协作设计、实时响应能力。 本篇作为 Day 6,将带你从理论、底层机制到真实…...
深入理解 Shell:从原理到实战的全方位解析
1. 引言:什么是 Shell? Shell 是操作系统中最基础却最强大的工具之一。它是用户与操作系统之间的接口,一个命令行解释器,它接收用户输入的命令并调用操作系统内核完成相应的操作。 Shell 的含义包括两层: 交互式命令…...