ListIterator:List 的双向迭代器
ListIterator vs Iterator
Iterator 只能向前走,ListIterator 可以向前也可以向后:
| 能力 | Iterator | ListIterator |
|---|---|---|
| 向前遍历 | ✅ | ✅ |
| 向后遍历 | ❌ | ✅ |
| 修改元素 | ❌ | ✅ |
| 添加元素 | ❌ | ✅ |
| 获取当前位置 | ❌ | ✅ |
获取方式也不同:
java
// Iterator:所有 Collection 都有
Iterator<E> it = collection.iterator();
// ListIterator:只有 List 有
ListIterator<E> it = list.listIterator();双向遍历
ListIterator 有一个「隐式游标」在元素之间:
元素: [A] [B] [C] [D]
游标位置: ^ ^ ^ ^ ^
| | | | |
索引位置: 0 1 2 3 4基础双向遍历
java
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
ListIterator<String> it = list.listIterator();
// 正向:从游标位置向后走
while (it.hasNext()) {
int idx = it.nextIndex();
String val = it.next();
System.out.println("索引 " + idx + ": " + val);
}
// 此时游标在末尾(-1 之后)
// 反向:从游标位置向前走
while (it.hasPrevious()) {
int idx = it.previousIndex();
String val = it.previous();
System.out.println("索引 " + idx + ": " + val);
}修改元素:set()
set() 修改上一个 next() 或 previous() 返回的元素:
java
List<String> list = new ArrayList<>(Arrays.asList("A", "b", "C"));
ListIterator<String> it = list.listIterator();
while (it.hasNext()) {
String val = it.next();
// 将小写字母转为大写
if (val.equals(val.toLowerCase())) {
it.set(val.toUpperCase()); // 修改当前元素
}
}
System.out.println(list); // [A, B, C]添加元素:add()
add() 在游标前面插入新元素,然后游标移到新元素之后:
java
List<String> list = new ArrayList<>(Arrays.asList("A", "C"));
ListIterator<String> it = list.listIterator();
// 移动到 "A" 之后
it.next();
// 在 "A" 和 "C" 之间插入 "B"
it.add("B");
System.out.println(list); // [A, B, C]有序插入:利用游标特性
ListIterator 的游标特性让它非常适合有序插入:
java
// 在有序 List 中插入元素,保持有序
public static <T extends Comparable<T>> void insertSorted(List<T> list, T item) {
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
T current = it.next();
// 如果当前元素比要插入的大,就退回去
if (current.compareTo(item) > 0) {
it.previous();
break;
}
}
it.add(item); // 在正确位置插入
}
// 测试
List<Integer> sorted = new ArrayList<>(Arrays.asList(1, 3, 5, 7));
insertSorted(sorted, 4);
System.out.println(sorted); // [1, 3, 4, 5, 7]替换所有匹配元素
java
// 用 ListIterator 实现 replaceAll
public static <T> void replaceAll(List<T> list, T oldVal, T newVal) {
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
if (Objects.equals(oldVal, it.next())) {
it.set(newVal);
}
}
}
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "a", "c"));
replaceAll(list, "a", "X");
System.out.println(list); // [X, b, X, c]游标位置控制
java
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
ListIterator<String> it = list.listIterator();
// 从指定索引开始:从索引 2 开始(C)
it = list.listIterator(2);
System.out.println("从索引 2 开始: " + it.next()); // C
// 在任意位置插入
it = list.listIterator(2); // 回到索引 2
it.add("X"); // 在 C 前面插入 X
System.out.println(list); // [A, B, X, C, D, E]总结
| 要点 | 说明 |
|---|---|
| 获取方式 | list.listIterator() 或 list.listIterator(index) |
| 向前 | hasNext() + next() |
| 向后 | hasPrevious() + previous() |
| 修改 | set(element) ——修改上一个遍历返回的元素 |
| 添加 | add(element) ——在游标前插入 |
| 删除 | remove() ——删除上一个遍历返回的元素 |
| 适用 | 仅限 List,Set/Map 不支持 |
一句话:ListIterator 是 Iterator 的「升级版」——双向移动、随意修改,是 List 遍历的瑞士军刀。
