彻底搞懂「迭代器 Iterator」与「游标 Cursor」—— 同源异路的遍历设计

张开发
2026/4/21 17:08:35 15 分钟阅读

分享文章

彻底搞懂「迭代器 Iterator」与「游标 Cursor」—— 同源异路的遍历设计
在日常开发与源码阅读中迭代器Iterator和游标Cursor是两个高频出现的概念。很多人会疑惑它们到底是不是一回事有什么区别又为什么经常被放在一起比较本文基于最本质的设计思想从相同点、区别、代码示例、应用场景完整讲透帮你一次彻底理解。一、先破误区它们本质是同一个设计思想很多资料把迭代器和游标讲得完全割裂但从设计模式角度看迭代器模式 游标模式Cursor Pattern二者核心思想完全同源只是应用领域、实现方式、生命周期不同。可以直接记一句最本质的话迭代器是内存集合的游标游标是数据库结果集的迭代器。二、核心相同点为什么说它们本质一样这是理解底层设计最重要的部分也是很多人忽略的关键点。1. 都是「位置指针」不存储数据无论迭代器还是游标本身不保存任何数据只做一件事标记当前遍历到哪个位置。迭代器指向集合中某元素的位置游标指向结果集中某一行的位置它们都是轻量位置指示器。2. 都是「惰性遍历」不一次性加载两者都遵循按需读取不取不加载读一个移动一次再读下一个不会把整个集合/结果集全部载入内存这是它们能处理大数据量、流式数据的根本原因。3. 都提供统一的遍历接口行为高度一致核心操作几乎一模一样判断是否还有元素hasNext/FETCH STATUS移动到下一个next/FETCH NEXT获取当前元素current/当前行接口抽象逻辑完全相同。4. 都隐藏底层结构对外统一访问迭代器不管底层是数组、链表、树、哈希表遍历方式一致游标不管数据库存储结构是 B树、堆表取行方式一致面向接口不暴露内部实现这是封装的核心体现。5. 都支持单向顺序遍历基础形态最朴素的迭代器与游标都是从前到后、顺序访问这是它们最原始的设计形态。三、代码示例直观感受二者逻辑高度一致示例1Java 迭代器内存集合importjava.util.Arrays;importjava.util.Iterator;importjava.util.List;publicclassIteratorDemo{publicstaticvoidmain(String[]args){ListStringlistArrays.asList(张三,李四,王五);// 获取迭代器相当于打开游标IteratorStringitlist.iterator();// hasNext判断是否还有数据while(it.hasNext()){// next移动指针并获取当前元素Stringnameit.next();System.out.println(当前元素name);}// 迭代器无需手动关闭GC 自动回收}}核心动作hasNext()→ 判断是否有下一个next()→ 移动指针 取数据示例2MySQL 存储过程游标数据库-- 定义游标逐行遍历用户表DELIMITER//CREATEPROCEDUREcursorDemo()BEGINDECLAREu_nameVARCHAR(50);DECLAREdoneINTDEFAULT0;-- 1. 声明游标类似获取 iterator()DECLAREuser_curCURSORFORSELECTnameFROMuserLIMIT3;-- 2. 遍历结束标志类似 !hasNext()DECLARECONTINUEHANDLERFORNOTFOUNDSETdone1;-- 3. 打开游标初始化OPENuser_cur;-- 循环遍历read_loop:LOOP-- 4. 获取当前行类似 next()FETCHuser_curINTOu_name;IFdone1THENLEAVEread_loop;ENDIF;SELECTCONCAT(当前行,u_name)ASinfo;ENDLOOP;-- 5. 必须关闭游标释放资源CLOSEuser_cur;END//DELIMITER;CALLcursorDemo();游标核心动作OPEN→ 初始化FETCH→ 移动指针 取当前行CLOSE→ 释放资源可以清晰看到迭代器与游标代码逻辑几乎一一对应。四、关键区别相同灵魂不同肉身虽然思想同源但应用场景决定了它们的差异巨大。1. 应用领域不同迭代器编程语言层面内存集合遍历List、Set、Map、Stream、生成器等游标数据库层面结果集逐行控制SQL 查询返回的 ResultSet服务端状态对象2. 轻重级别不同迭代器极轻量只是一个对象位置索引无资源占用游标重量级占用数据库连接、服务端内存、事务上下文、锁资源3. 生命周期与管理迭代器用完即废无需手动关闭游标必须显式 OPEN / CLOSE / DEALLOCATE忘记关闭会导致资源泄漏、连接占满、锁不释放4. 功能能力不同迭代器以只读、单向遍历为主大部分标准迭代器不支持回退、修改游标功能更强可控制可前后滚动、定位、修改当前行、删除当前行5. 数据来源不同迭代器内存数据游标磁盘/网络数据五、极简总结表对比维度迭代器 Iterator游标 Cursor本质位置指针位置指针设计模式迭代器模式游标模式同一模式遍历方式惰性、逐个、流式惰性、逐个、流式存储位置内存数据库服务器重量轻量重量级资源无额外资源占连接、内存、锁关闭自动失效必须手动关闭功能单向遍历为主可滚动、可修改、可定位适用场景语言集合遍历数据库大结果集逐行处理六、各自的应用场景与最佳实践迭代器的典型场景遍历内存中的集合列表、字典、集合实现生成器或懒加载列表例如读取大文件的行流水线式数据处理函数式编程中的 map、filter为自定义数据结构提供标准遍历接口✅ 优先使用迭代器除非你要处理数据库中的数据。游标的典型场景游标在数据库开发中名声不太好——因为它通常比基于集合的操作如UPDATE … WHERE慢一个数量级。但某些场景下你不得不使用它需要逐行执行复杂业务逻辑无法用一条 SQL 完成调用每行数据都不同的存储过程或外部 API实现分批提交以避免长事务锁定处理分页但通常用 LIMIT/OFFSET 或键集分页更优某些高级需求可滚动游标、敏感游标反映他人提交的更改❌不要为了“看起来像代码”而用游标代替批量 SQL。七、一句话终极理解最精髓迭代器与游标本质完全相同——都是「带位置的遍历抽象」。只是一个运行在内存语言层一个运行在数据库服务层。懂了这句话你就真正理解了遍历设计的核心位置 移动 取值 隐藏底层结构。

更多文章