listiterator 是 list 专属双向迭代器,支持正向/反向遍历及安全增删改元素;其通过游标定位间隙实现双向操作,修改方法需在 next()/previous() 后调用。

ListIterator 是 Java 中 List 接口专属的迭代器,它支持**双向遍历(向前/向后)**,还能在遍历过程中**安全地添加、删除、替换元素**,这是普通 Iterator 不具备的能力。
为什么 ListIterator 能双向遍历?
因为它内部维护一个“游标位置”(cursor),指向两个相邻元素之间的间隙(类似插入点),而不是直接指向某个元素。这个位置决定了:
-
next()从游标当前位置向后取元素,然后游标前移 -
previous()从游标当前位置向前取元素,然后游标后退 - 初始时游标在索引 0 之前(即开头),所以第一次调用
previous()会抛异常,而next()可正常执行
如何用 ListIterator 实现正向 + 反向遍历?
关键在于灵活切换 next() 和 previous(),并配合 hasNext()/hasPrevious() 判断边界:
List<string> list = new ArrayList(Arrays.asList("a", "b", "c"));
ListIterator<string> lit = list.listIterator();
// 正向遍历
while (lit.hasNext()) {
System.out.print(lit.next() + " "); // 输出:a b c
}
System.out.println();
// 此时游标已在末尾(索引 3 的位置)
// 反向遍历(无需重新获取迭代器)
while (lit.hasPrevious()) {
System.out.print(lit.previous() + " "); // 输出:c b a
}
</string></string>
怎么在遍历中安全修改元素?
ListIterator 提供三个修改方法,都要求**必须先调用 next() 或 previous() 成功之后才能使用**(否则抛 IllegalStateException):
-
set(E e):替换上一次next()或previous()返回的元素(即“刚访问过的那个”) -
add(E e):在游标当前位置插入新元素,插入后游标落在新元素之后 -
remove():删除上一次next()或previous()访问的元素(只能删一次,重复调用会异常)
示例:把偶数索引位置的元素替换成大写,并在 "b" 后插入 "x"
List<string> list = new ArrayList(Arrays.asList("a", "b", "c", "d"));
ListIterator<string> lit = list.listIterator();
int index = 0;
while (lit.hasNext()) {
String s = lit.next();
if (index % 2 == 0) {
lit.set(s.toUpperCase()); // 替换 a → A, c → C
}
if ("b".equals(s)) {
lit.add("x"); // 在 b 后插入 x → ["A", "b", "x", "C", "d"]
}
index++;
}
</string></string>
注意几个易错点
- 不能对
LinkedList或ArrayList以外的 List 实现(如Collections.unmodifiableList())调用listIterator(),否则可能抛UnsupportedOperationException -
set()和remove()都依赖“上次访问动作”,中间穿插add()不影响它们的上下文,但连续两次next()后再set(),只会修改第二次拿到的元素 - 遍历时用
list.add()或list.remove()会破坏迭代器状态,导致ConcurrentModificationException;必须只用 ListIterator 自己的方法修改
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











