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. 合理使用索引定位功能

相关推荐
韩立学长2 小时前
【开题答辩实录分享】以《足球球员数据分析系统开题报告》为例进行选题答辩实录分享
java·数据库·mysql
牧小七2 小时前
Java CompletableFuture 使用详解
java
AndrewHZ2 小时前
【Python与生活】怎么用python画出好看的分形图?
开发语言·python·生活·可视化·递归·分形
jiayong232 小时前
MINA框架面试题 - 实战篇
java·io·mina
陳10302 小时前
C++:继承
开发语言·c++
GSDjisidi2 小时前
正社員・個人事業主歓迎|GSD東京本社で働こう|業界トップクラスの福利厚生完備
开发语言·面试·职场和发展
数智工坊2 小时前
【操作系统-处理器调度】
java·linux·服务器·windows·ubuntu
xiaoye-duck2 小时前
C++ string 类使用超全攻略(下):修改、查找、获取及常见实用接口深度解析
开发语言·c++·stl