必须用当前迭代器的remove()方法删除,且仅在next()后立即调用一次;嵌套时需内外层迭代器完全独立,避免交叉调用;推荐倒序索引遍历或Java 8+的removeIf()。

在嵌套循环中用 Iterator 安全删除元素,核心原则只有一条:**必须用当前迭代器的 remove() 方法删除,且只能在调用过 next() 后立即调用一次**。嵌套时容易误用外层或内层迭代器,导致 ConcurrentModificationException 或漏删/错删。
避免在嵌套中混用不同层级的迭代器
常见错误是外层用 for-each(隐式迭代器),内层用显式 Iterator,或两个显式迭代器交叉调用 remove()。Java 的 ArrayList、LinkedList 等非并发集合,其迭代器是“快速失败”(fail-fast)的——只要集合结构被任意线程或任何迭代器修改(包括其他迭代器的 remove()),未完成的迭代器就会抛异常。
- ❌ 错误示例:外层 for-each + 内层 iterator.remove()
- ✅ 正确做法:内外层都用独立、不交叉的
Iterator,且每个remove()仅作用于它所属的迭代器刚返回的元素
双层嵌套安全删除的推荐写法
假设要遍历 List<list>></list>,删除所有空子列表,同时删除每个子列表中的空字符串:
Iterator<list>> outerIter = listOflists.iterator();
while (outerIter.hasNext()) {
List<string> innerList = outerIter.next();
<pre class="brush:php;toolbar:false;">// 单独创建内层迭代器,操作 innerList
Iterator<string> innerIter = innerList.iterator();
while (innerIter.hasNext()) {
if (innerIter.next().isEmpty()) {
innerIter.remove(); // ✅ 安全:删的是 innerIter 刚取的元素
}
}
// 内层处理完后,再决定是否删整个 innerList
if (innerList.isEmpty()) {
outerIter.remove(); // ✅ 安全:删的是 outerIter 刚取的元素
}</string>
}
关键点:
- 外层和内层迭代器完全独立,生命周期不重叠干扰
- 每个 remove() 都紧跟在对应 next() 之后,且只调用一次
- 不在内层循环里调用外层迭代器的 remove(),也不反之
替代方案:倒序索引遍历(适合 List)
如果集合是 ArrayList 这类支持随机访问的 List,用倒序 for 循环可避免 Iterator 的复杂性,也天然规避并发修改问题:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 外层从
listOflists.size()-1往 0 遍历 - 内层对每个
innerList同样倒序遍历(i = innerList.size()-1到 0) - 删除时用
list.remove(i),不会影响尚未检查的索引
注意:倒序不适用于 LinkedList(get(i) 效率低),但 remove(i) 对 ArrayList 是高效的。
更简洁的现代写法(Java 8+)
若逻辑允许,优先用声明式 API 替代嵌套迭代:
- 用
removeIf()清理内层:innerList.removeIf(String::isEmpty) - 外层再用
removeIf()清理空子列表:listOflists.removeIf(List::isEmpty)
removeIf() 内部使用迭代器并保证安全,代码清晰且不易出错。它等价于手动写正确迭代器逻辑,但更简短、意图更明确。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










