Iterator 不支持遍历中插入元素,因其仅定义 hasNext()、next()、remove() 方法且依赖 modCount 检测结构性修改;替代方案包括使用 ListIterator(仅 List)、两阶段批量添加或线程安全容器。

Java 中的 Iterator 本身**不支持在遍历过程中动态插入新元素**。这是由其设计原则决定的:迭代器是“只读快照”,用于安全遍历集合,而非修改结构。
为什么 Iterator 不能插入元素?
Iterator 接口只定义了 hasNext()、next() 和 remove() 三个方法,没有 add() 或类似操作。它的底层实现(如 ArrayList.Itr)会检查 modCount(修改计数),一旦检测到集合被结构性修改(如调用 list.add()),就会抛出 ConcurrentModificationException。
替代方案:使用 ListIterator(仅限 List)
如果目标集合是 List(如 ArrayList 或 LinkedList),可用 ListIterator —— 它是 Iterator 的子接口,支持双向遍历和插入:
-
add(E e):在当前游标位置(即上次调用next()或previous()返回的元素之后)插入元素 - 插入后,新元素成为下一次
next()的返回对象,且不影响后续遍历逻辑 - 必须先调用
next()或previous()建立游标位置,否则行为未定义(部分实现可能抛IllegalStateException)
示例:
List<string> list = new ArrayList(Arrays.asList("a", "b", "c"));
ListIterator<string> lit = list.listIterator();
while (lit.hasNext()) {
String s = lit.next();
if ("b".equals(s)) {
lit.add("x"); // 在 "b" 后插入 "x"
}
}
// 结果:["a", "b", "x", "c"]</string></string>通用方案:收集待插入元素,遍历结束后批量添加
若集合类型不限于 List(如 Set、Map.values()),或需更灵活控制,推荐“两阶段法”:
- 第一阶段:用普通
Iterator遍历,将要插入的新元素暂存到另一个集合(如ArrayList) - 第二阶段:遍历结束后,调用原集合的
addAll()(对Collection)或逐个put()(对Map)完成插入 - 注意:对
Set插入重复元素会被自动忽略;对Map需确保 key 不冲突
高并发场景:用线程安全容器 + 迭代器配合
若在多线程中需要边遍历边插入,避免 ConcurrentModificationException 和数据竞争:
- 选用
CopyOnWriteArrayList:它的迭代器基于快照,遍历时允许其他线程修改原列表(但插入不会反映在当前迭代中) - 选用
ConcurrentLinkedQueue或ConcurrentHashMap:提供弱一致性迭代器,不抛并发异常,但不保证实时可见性 - 关键点:这些容器的
Iterator仍不提供add()方法,插入仍需调用容器自身的添加方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











