ListIterator 是 Java 中专为 List 设计的双向迭代器,支持前后遍历、安全增删改元素;它通过游标定位、set() 替换上次访问元素、add() 插入游标处、remove() 删除上次访问元素,且必须由 List.listIterator() 获取。

ListIterator 是 Java 中专为 List 设计的双向迭代器,它既能从前往后、也能从后往前遍历,还支持在遍历过程中安全地添加、删除、替换元素——这是普通 Iterator 不具备的能力。
双向遍历:用 hasPrevious() / previous() 和 hasNext() / next()
与单向 Iterator 不同,ListIterator 维护一个“游标”位置(初始在索引 0 之前),通过两组方法控制方向:
-
hasNext()和next():向后移动(正向),返回当前元素并把游标移到下一个位置 -
hasPrevious()和previous():向前移动(反向),返回当前元素前一个,并把游标左移一位 - 调用
nextIndex()得到下一次next()将返回的元素索引;previousIndex()返回下一次previous()将返回的元素索引(若游标在开头则为 -1)
例如遍历 [A, B, C],初始游标在 A 前(nextIndex() == 0,previousIndex() == -1);调用一次 next() 后,返回 A,游标在 A 和 B 之间(nextIndex() == 1,previousIndex() == 0)。
修改元素:set() 替换上一次 next() 或 previous() 返回的元素
set(E e) 方法只能在调用过 next() 或 previous() 之后立即使用,且不能紧接在 add() 或 remove() 之后调用。它的作用是**替换最近一次由迭代器返回的那个元素**,不改变列表长度和结构。
立即学习“Java免费学习笔记(深入)”;
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 如果刚调用
next()得到 B,再调用set("X"),就把 B 改成 X - 如果刚调用
previous()回退到 B,再set("Y"),同样修改的是 B - 若尚未调用
next()/previous(),或上次操作是add()/remove(),调用set()会抛IllegalStateException
增删元素:add() 插入、remove() 删除当前游标左侧元素
add(E e) 在游标当前位置插入新元素,插入后新元素成为 previous() 的返回值,原游标右侧元素索引全部 +1;remove() 删除上一次 next() 或 previous() 返回的元素(即游标左侧那个)。
-
add()总是成功,不会抛异常(除非元素本身不合法,如 null 且 list 不允许) -
remove()必须在调用过next()或previous()后调用,否则抛IllegalStateException - 连续两次
remove()会失败,因为中间缺少一次next()/previous()
注意:remove() 和 set() 都作用于“上一次遍历操作访问的元素”,不是“游标指向的位置”。游标本身始终位于两个元素之间(或首尾外侧)。
获取 ListIterator:必须通过 List.listIterator() 获取
不能直接 new,必须调用 List 实例的 listIterator() 方法:
-
list.listIterator():从头开始(游标在索引 0 前) -
list.listIterator(int index):从指定索引位置开始(游标在该索引元素之前,比如list.listIterator(2)表示游标在索引 2 元素前,即第三个元素左边)
底层实现依赖于具体 List 类型:比如 ArrayList 的 ListIterator 是内部类,记录当前索引;LinkedList 则基于节点引用,支持 O(1) 双向移动。

















