Java中Iterator实现集合解耦的核心是分离存储与遍历:聚合接口仅声明iterator(),禁止直接访问方法;具体索引返回专属轻量迭代器,按需惰性加载、只读无状态;外部统一使用Iterator<T>,配合Stream API和依赖注入保障一致性。

Java 中 Iterator 迭代器规范集合解耦设计,核心是把“数据存哪”和“怎么取数据”彻底分开——集合只管存储与维护,遍历逻辑全交给独立的迭代器对象。
明确聚合接口职责,不暴露内部结构
定义统一的聚合接口(如 IndexCollection<T>),只声明 iterator() 方法,禁止提供 get(i)、values()、entrySet() 等直接访问或快照方法。这样外部组件无法绕过迭代器去触碰底层实现(比如 B+ 树节点、跳表层级、哈希桶数组)。
- 具体索引类(如
InMemoryBTreeIndex)只负责持有数据,并返回专属迭代器实例 - 所有索引实现都实现同一接口,客户端代码完全不感知底层是树、表还是图
- 避免在聚合类中写 for 循环或索引遍历逻辑,否则就退回了强耦合状态
迭代器只读、无状态、按需推进
每个具体迭代器(如 TreeIndexIterator 或 HashIndexIterator)应设计为轻量、无业务数据副本、仅维护当前位置的游标对象:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 构造时接收索引的弱引用或快照视图(如
LockFreeSnapshotView),防止遍历时被写操作干扰 - 不缓存全部元素,
next()调用才触发真实查找,支持百万级数据的惰性加载 - 禁止在迭代器中修改集合;如需删除,应通过受控的
remove()(且仅限当前元素),或交由上层协调
对外交付标准 Iterator<T>,不传原始容器
外部组件(搜索服务、统计模块、导出工具)拿到的永远是 Iterator<Product>,不是 List<Product>、Map<ID, Product> 或自定义集合类:
立即学习“Java免费学习笔记(深入)”;
- Spring 注入点统一用
IndexCollection<Product>,业务代码调用iterator()后直接传给处理器 - 配合 Stream API 使用:
StreamSupport.stream(index.iterator().spliterator(), false) - 过滤、映射等操作封装新迭代器(如
FilteringIterator),不生成中间集合,避免内存爆炸
依赖注入保障单例与一致性
索引实体必须是应用生命周期内唯一的稳定实例,否则每次 iterator() 返回的可能是不同快照,破坏数据一致性:
- 启动时通过工厂创建唯一索引:
IndexFactory.createBTreeIndex(config) - 迭代器本身无状态,可频繁新建;但背后聚合对象需线程安全或带版本控制
- 避免在每次遍历前 new 一个新索引,那会丢失实时性,也违背“解耦”本意

















