ListIterator 的 set() 方法只能替换上一次 next() 或 previous() 返回的元素,未调用过遍历方法或上次为 add() 时调用会抛 IllegalStateException;它不改变列表结构,仅原地更新值。

Java 中 ListIterator 允许在遍历过程中安全地修改列表元素,但必须使用其自带的 set() 方法,不能直接调用集合的 set() 或 add()(除非配合 add() 方法插入新元素),否则会抛出 ConcurrentModificationException。
必须先调用 next() 或 previous() 才能 set()
set(E e) 方法只能替换**上一次由 next() 或 previous() 返回的元素**。也就是说,它不作用于“当前位置”,而是作用于“刚刚访问过的那个元素”。如果尚未调用过 next() 或 previous(),或上次操作是 add(),调用 set() 会抛出 IllegalStateException。
- 正向遍历时:调用
next()获取元素后,立刻可用set()替换它 - 反向遍历时:调用
previous()获取元素后,立刻可用set()替换它 - 不能在
add()后直接set()—— 因为add()不产生“上一个返回元素”
set() 是替换,不是插入或删除
set() 不改变列表结构(长度、索引偏移不变),只是原地更新值。它和 list.set(index, e) 效果一致,但更安全,因为它与迭代状态绑定,避免越界或并发修改问题。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 例如:
list = ["a", "b", "c"],用listIterator()遍历到 "b" 后调用set("x")→ 列表变为["a", "x", "c"] - 不会影响后续
next()的行为(下一次仍返回 "c")
修改时注意迭代器状态和方向
同一个 ListIterator 实例可双向遍历,但 set() 总是作用于最近一次 next() 或 previous() 访问的元素,与当前游标位置无关。混用正向/反向操作时需格外留意“上一个访问的是谁”。
立即学习“Java免费学习笔记(深入)”;
- 示例:从头开始
next()到第 1 个元素("a"),set("A")→ 成功 - 再
next()到 "b",然后previous()回到 "a"(此时 "a" 是上次访问元素),再set("X")→ 实际替换的是 "a"(即现在的 "A") - 若中间穿插了
add(),则之后不能再set(),直到再次调用next()或previous()
对比 add() 和 remove() 的修改能力
ListIterator 还支持 add(E)(在当前位置前插入)和 remove()(删除上一次 next() 或 previous() 返回的元素),三者互斥使用:
-
next()→ 可set()或remove() -
previous()→ 可set()或remove() -
add()→ 清除上一个访问标记,之后不能set()或remove(),除非再调用next()/previous()

















