iterator 实现平滑检索的核心是解耦访问逻辑与存储结构,通过封装位置状态、自动推进、安全边界判断及统一接口,确保连续、无跳变、不越界、不重复、不遗漏地逐个获取元素。

用 Iterator 实现不依赖下标的元素平滑检索,核心在于把“访问逻辑”和“存储结构”解耦。Iterator 本身不是数据结构,而是对底层数据结构(如 ArrayList 的数组、LinkedList 的链表、HashSet 的哈希桶)的统一访问抽象。它不关心元素存在哪,只负责按序“推着走”——这正是平滑检索的关键。
Iterator 为什么天然支持平滑检索
平滑检索指:连续、无跳变、不越界、不重复、不遗漏地逐个获取元素,且不暴露内部索引或指针细节。Iterator 满足这个要求,因为:
- 它封装了位置状态(如 cursor 和 lastRet),每次 next() 自动推进,无需手动维护下标变量
- hasNext() 提供安全边界判断,避免 IndexOutOfBoundsException 或空指针
- 无论底层是数组、链表还是散列表,调用方式完全一致,检索流程“平滑”不变
配合不同集合的数据结构特点使用
虽然 Iterator 接口统一,但实际检索体验受底层结构影响。合理利用这点,能让检索更高效、更稳定:
- ArrayList(动态数组):Iterator 内部用 int cursor 记录当前下标,next() 是 O(1) 数组访问,适合高频顺序遍历
- LinkedList(双向链表):Iterator 维护节点引用而非下标,next() 是 O(1) 指针移动,适合边遍历边删(remove() 不触发重排)
- HashSet / HashMap(哈希表):Iterator 遍历的是 Node[] table 中的链表/红黑树节点,顺序由 hash 分布决定,无序但稳定——只要集合不扩容/重构,同一数据多次迭代顺序一致
实现真正平滑的检索操作技巧
平滑不只是“能跑通”,还要应对删除、中途退出、异常等现实场景:
- 删除元素必须用 it.remove(),不能调 collection.remove(),否则触发 ConcurrentModificationException
- 若需“查找并停在某元素”,可用 while(it.hasNext()) { E e = it.next(); if (match(e)) break; },无需提前知道索引
- 避免在循环中反复调 it.hasNext() 多次——它只是检查,不推进;而 next() 才真正消耗一个元素
- 对 List 类集合,如需双向或定位,可升级为 ListIterator,支持 hasPrevious()、previous() 和 add()
一个不依赖下标、可中断、可删除的平滑检索示例
假设从一个混合类型 ArrayList 中找第一个字符串并转大写,同时移除所有数字:
Iterator<object> it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
if (obj instanceof String) {
System.out.println(((String) obj).toUpperCase());
break; // 平滑停止,不继续遍历
} else if (obj instanceof Integer || obj instanceof Number) {
it.remove(); // 安全删除,不影响后续 next()
}
}</object>
整个过程没出现任何下标、没调用 get(i)、没用 size() 做循环控制,完全靠 Iterator 的状态流转完成——这就是数据结构与 Iterator 协同实现的平滑检索。











