java基础-ListIterator 接口

ListIterator 是 Java 集合框架中一个功能强大的迭代器,专为 List 接口设计。它扩展了 Iterator 接口,提供了双向遍历和更多操作功能。

Java ListIterator 接口详解

1. 基本特点

java 复制代码
public interface ListIterator<E> extends Iterator<E> {
    // 新增的方法
    boolean hasPrevious();
    E previous();
    int nextIndex();
    int previousIndex();
    void set(E e);
    void add(E e);
    
    // 继承自 Iterator
    boolean hasNext();
    E next();
    void remove();
}

2. 获取 ListIterator 对象

java 复制代码
import java.util.*;

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));

// 获取 ListIterator
ListIterator<String> iterator = list.listIterator();          // 从开头
ListIterator<String> iterator2 = list.listIterator(2);       // 从索引2开始

3. 核心方法详解

遍历方法
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("Java", "Python", "C++"));

ListIterator<String> it = list.listIterator();

// 正向遍历
while (it.hasNext()) {
    System.out.println(it.next() + " [index: " + it.nextIndex() + "]");
    // 输出: Java [index: 1], Python [index: 2], C++ [index: 3]
}

// 反向遍历
while (it.hasPrevious()) {
    System.out.println(it.previous() + " [previous index: " + it.previousIndex() + "]");
    // 输出: C++ [previous index: 1], Python [previous index: 0], Java [previous index: -1]
}
修改方法
java 复制代码
List<String> languages = new ArrayList<>(Arrays.asList("Java", "Python", "JavaScript"));

ListIterator<String> it = languages.listIterator();

// 替换元素
it.next(); // 移动到 "Java"
it.set("Java SE"); // 替换当前元素

// 添加元素
it.next(); // 移动到 "Python"
it.add("C++"); // 在 "Python" 之前添加
// 现在列表: ["Java SE", "C++", "Python", "JavaScript"]

// 删除元素
it.next(); // 移动到 "Python"
it.remove(); // 删除 "Python"

4. 使用示例

示例1:双向遍历和修改
java 复制代码
public class ListIteratorExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        ListIterator<Integer> it = numbers.listIterator();
        
        // 正向遍历并加倍奇数
        while (it.hasNext()) {
            int num = it.next();
            if (num % 2 != 0) {
                it.set(num * 2);
            }
        }
        System.out.println("修改后: " + numbers); // [2, 2, 6, 4, 10]
        
        // 反向遍历并插入元素
        while (it.hasPrevious()) {
            int index = it.previousIndex();
            int num = it.previous();
            if (index % 2 == 0) {
                it.add(num * 10); // 在偶数索引位置插入
            }
        }
        System.out.println("最终结果: " + numbers); 
        // [20, 2, 2, 60, 6, 4, 100, 10]
    }
}
示例2:列表反转
java 复制代码
public class ListReverser {
    public static <T> void reverse(List<T> list) {
        ListIterator<T> forward = list.listIterator();
        ListIterator<T> backward = list.listIterator(list.size());
        
        for (int i = 0, mid = list.size() / 2; i < mid; i++) {
            T temp = forward.next();
            forward.set(backward.previous());
            backward.set(temp);
        }
    }
    
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
        reverse(list);
        System.out.println(list); // [E, D, C, B, A]
    }
}

5. 重要规则和注意事项

调用顺序规则:
java 复制代码
ListIterator<String> it = list.listIterator();

// 错误示例(会抛出 IllegalStateException)
it.remove();  // × 没有调用 next() 或 previous()
it.set("X");  // × 没有调用 next() 或 previous()

// 正确使用
it.next();    // √
it.remove();  // √ 可以调用

it.next();    // √
it.set("X");  // √ 可以调用

it.add("Y");  // √ 随时可以调用
// 注意:add() 后不能立即调用 remove() 或 set()
并发修改检查:
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
ListIterator<String> it1 = list.listIterator();
ListIterator<String> it2 = list.listIterator();

it1.next();
it1.add("X"); // 通过 it1 修改列表

// it2.next(); // 会抛出 ConcurrentModificationException
// 因为列表被其他迭代器修改了

6. 与 Iterator 的比较

特性 Iterator ListIterator
遍历方向 单向(向前) 双向(向前/向后)
遍历时修改 只能删除 添加、删除、替换
获取索引 不支持 支持(nextIndex(), previousIndex())
适用范围 所有 Collection 仅 List
起始位置 只能从开头 可以指定起始位置

7. 性能考虑

  1. 对于 ArrayList: ListIterator 提供 O(1) 的访问时间

  2. 对于 LinkedList: 需要小心使用,频繁的 previous() 调用可能影响性能

  3. 内存占用: 每个 ListIterator 需要维护当前位置和修改计数

总结

ListIterator 是处理 List 集合最强大的工具之一,特别适合需要:

  • 双向遍历

  • 遍历时修改(添加、删除、替换)

  • 需要知道当前位置索引

  • 实现复杂列表算法

关键要点:

  1. 始终检查 hasNext()/hasPrevious() 避免异常

  2. 注意 add()remove()set() 的调用顺序限制

  3. 理解并发修改的约束

  4. 合理使用索引定位功能

相关推荐
Dxy12393102161 分钟前
Python序列标注模型上下文纠错详解
开发语言·python
孙鹏宇.1 分钟前
左值右值.
java·开发语言
XDHCOM5 分钟前
Redis节点故障自动恢复机制详解,如何快速抢救故障节点,确保数据不丢失?
java·数据库·redis
风吹迎面入袖凉6 分钟前
【Redis】Redisson分布式锁原理
java·服务器·开发语言
A.A呐7 分钟前
【QT第五章】系统相关
开发语言·qt
QCzblack7 分钟前
BugKu BUUCTF ——Reverse
java·前端·数据库
Orange_sparkle11 分钟前
learn claude code学习记录-S02
java·python·学习
李白你好12 分钟前
Java GUI-未授权漏洞检测工具
java·开发语言
leo__52027 分钟前
拉丁超立方抽样(Latin Hypercube Sampling, LHS)MATLAB实现
开发语言·matlab
sycmancia29 分钟前
Qt——Qt中的标准对话框
开发语言·qt