ListIterator 能双向遍历是因为它基于光标机制并提供 next()/hasNext() 和 previous()/hasPrevious() 两组方向明确的方法,初始光标位于索引-1位置。

ListIterator 是 Java 中 List 接口专属的迭代器,它支持**双向遍历**(向前和向后)、元素修改、插入和获取索引位置,比普通 Iterator 更灵活。
为什么 ListIterator 能双向遍历?
因为它提供了两组方向明确的方法:
-
向前遍历:用
next()和hasNext()—— 从当前光标位置向列表末尾走; -
向后遍历:用
previous()和hasPrevious()—— 从当前光标位置向列表开头走。
关键在于它的“光标”概念:初始时位于索引 0 之前(即 -1 位置),next() 移动到索引 0 并返回该元素;previous() 则只在光标不在开头时才有效。
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java
如何创建并使用 ListIterator?
只能通过 List 实例的 listIterator() 方法获得(不能 new):
立即学习“Java免费学习笔记(深入)”;
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
ListIterator<String> lit = list.listIterator(); // 光标起始在 -1 位置
常用操作示例:
- 正向遍历并打印:
while (lit.hasNext()) System.out.println(lit.next()); - 反向遍历(需先走到末尾):
lit = list.listIterator(list.size()); while (lit.hasPrevious()) System.out.println(lit.previous()); - 边遍历边修改:
lit.set("new")替换上一次next()或previous()返回的元素; - 在当前位置前插入:
lit.add("x")—— 插入后光标仍在新元素之后,下次next()返回原下一个元素。
注意几个易错点
-
next()和previous()都会移动光标,连续调用两次next()会跳过一个元素; - 调用
set()前必须至少调用过一次next()或previous(),否则抛IllegalStateException; -
add()后再调用set()会失败,因为add()会让上次访问失效; -
nextIndex()返回下一次next()的索引,previousIndex()返回下一次previous()的索引(不是当前元素索引)。
对比 Iterator 和 ListIterator
-
Iterator只能单向next(),不支持previous()、set()、add(); -
ListIterator仅适用于List,不支持Set或Map; - 二者都**快速失败(fail-fast)**:遍历中直接修改底层集合(如
list.remove())会触发ConcurrentModificationException,但用lit.remove()是安全的。

















