iterator.remove()是唯一安全的遍历中删除方式,必须先调用next()再调用remove(),否则抛illegalstateexception;其底层通过lastret状态校验确保调用顺序。

Java 的 Iterator.remove() 方法本身就有强制校验机制——它不会“防止”你出错,而是**在错误发生时立刻抛出 IllegalStateException**,从而让你明确知道调用顺序错了。这不是靠程序员自觉,而是由迭代器内部状态严格保障的。
remove() 前必须 next() 的底层原理
每次调用 it.next() 时,迭代器会:
- 把当前元素返回,并将内部游标前移;
- 同时标记“已准备好一个可删元素”,并更新一个私有状态(如
lastRet); -
it.remove()只有在lastRet >= 0时才允许执行,否则直接抛IllegalStateException。
典型错误与对应异常
以下写法运行时必定失败:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
-
Iterator<string> it = list.iterator(); it.remove();</string>→ 抛IllegalStateException(还没取任何元素) -
it.next(); it.remove(); it.remove();→ 第二个remove()抛IllegalStateException(上一次next()的“可删资格”已被消耗) -
for (String s : list) { it.remove(); }→ 编译不通过(it不在作用域内),或手动声明但未调next()→ 同样抛异常
如何写出天然防错的代码结构
把 next() 和条件判断绑定在同一个逻辑块里,避免“先取、后忘、再删”的松散写法:
- 用
while (it.hasNext()) { String s = it.next(); ... }包裹全部逻辑,确保每次remove()前必有next() - 删除操作只出现在
if分支内,且该分支紧接在next()赋值之后 - 绝不把
it.next()拆到循环外、或藏在方法调用里(如process(it.next())再删)
IDE 和静态检查能帮上忙吗
部分现代 IDE(如 IntelliJ)会在你写 it.remove() 但附近没有明显 it.next() 调用时标黄警告;Maven/Gradle 可接入 error-prone 或 spotbugs 插件,在编译期捕获这类模式。但这只是辅助,真正可靠的仍是清晰的 while + next + if 结构。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










