自定义迭代器防越界的核心是严格分离 hasnext() 检查与 next() 获取:hasnext() 必须精确判断下一次 next() 是否安全,基于实时 size 计算;next() 仅负责取值、推进状态并信任 hasnext() 的前置保障,不重复校验边界。

在自定义迭代器中防止越界异常,核心是把“检查”和“获取”严格分离——绝不跳过 hasNext() 直接调 next()。Java 的 Iterator 规范本身就依赖这个契约,自定义实现必须遵守,否则会抛 NoSuchElementException(而非 ArrayIndexOutOfBoundsException,但本质都是越界逻辑错误)。
确保 hasNext() 准确反映可访问状态
hasNext() 不应只是“还有没遍历的元素”,而要精确判断下一次调用 next() 是否安全。常见错误是缓存了当前索引却未同步更新边界值。
- 若底层是数组或 List,每次调用 hasNext() 都应基于
currentIdx 计算,不要复用旧的 size 值(尤其集合可能被外部修改) - 若支持 remove() 操作,需在 remove() 后将
lastRet置为 -1,并在 next() 中校验该状态,避免重复调用 next() 后再 remove() - 空集合时,构造迭代器后首次调用 hasNext() 必须返回 false
next() 内部不重复校验,但必须依赖 hasNext() 的前置保障
next() 方法本身不应再做完整边界检查(如再判一次 size),而是信任 hasNext() 已确认可取。它的职责是:安全取值 + 推进状态。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 取值前先检查
lastRet == -1(表示上一轮未成功调用 next() 或已 remove),此时直接抛NoSuchElementException - 取值后立即更新
currentIdx++和lastRet = 当前索引 - 返回元素,不修改底层集合结构(除非明确设计为“消费型”迭代器)
处理动态变化与并发场景
如果自定义迭代器需支持集合被外部修改(如多线程或回调中变更),应引入“快速失败”(fail-fast)机制:
- 在迭代器构造时记录集合的
modCount(如 ArrayList 的修改计数器) - 每次调用 hasNext() 或 next() 前,对比当前集合的 modCount;不一致则抛
ConcurrentModificationException - 这虽不防越界,但能及时暴露非法状态,避免因 size 缩小后仍按旧长度遍历导致的越界
避免手动索引偏移带来的隐形越界
不要在 next() 中写类似 array[currentIdx + 1] 这类带偏移的访问——它绕过了 hasNext() 的保护范围。
- 所有访问必须基于当前
currentIdx,且该索引只能由 hasNext() 允许的范围内推进 - 如需跳过元素(如 skip(2)),应在 hasNext() 中提前推进索引并重新校验,而不是让 next() 承担定位逻辑
- 增强 for 循环底层就是调用 hasNext()/next(),所以你的迭代器健壮了,foreach 就自然安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










