1. 概述

Iterator 是遍历集合的多种方式之一,每种方式都有其优缺点。它在 Java 1.2 中首次引入,作为 Enumeration 的替代品,并带来了以下改进:

  • ✅ 更直观的方法命名
  • ✅ 支持在遍历时安全移除集合元素(避免踩坑 ConcurrentModificationException
  • ⚠️ 不保证遍历顺序(除非集合实现明确保证)

本文将深入讲解 Iterator 接口的核心方法,并探讨其扩展接口 ListIterator 的增强功能。

2. Iterator 接口详解

2.1 获取 Iterator 实例

通过调用集合的 iterator() 方法获取 Iterator 实例。以 List 为例:

List<String> items = ...
Iterator<String> iter = items.iterator();

2.2 核心方法

2.2.1 hasNext()

检查是否还有剩余元素可遍历,通常用作循环条件:

while (iter.hasNext()) {
    // 处理逻辑
}

2.2.2 next()

获取下一个元素并移动指针:

String next = iter.next();

⚠️ 最佳实践:调用 next() 前务必先用 hasNext() 检查,否则可能抛出 NoSuchElementException

2.2.3 remove()

安全移除当前元素(最近一次 next() 返回的元素):

iter.remove();

这是遍历时修改集合的安全方式,不会触发 ConcurrentModificationException

2.3 完整示例

结合三个方法实现集合过滤:

while (iter.hasNext()) {
    String next = iter.next();
    System.out.println(next);
 
    if( "TWO".equals(next)) {
        iter.remove();  // 安全移除元素
    }
}

2.4 Lambda 表达式遍历

传统 Iterator 写法较繁琐,Java 8 引入 forEachRemaining 简化操作:

iter.forEachRemaining(System.out::println);

3. ListIterator 接口详解

ListIterator 是 Iterator 的增强版,专为 List 设计,支持双向遍历:

ListIterator<String> listIterator = items.listIterator(items.size()); // 从末尾开始

3.1 向前遍历

提供 hasPrevious()previous() 实现反向遍历:

while(listIterator.hasPrevious()) {
    String previous = listIterator.previous();
}

3.2 索引操作

获取当前元素的前后索引:

int nextIndex = listIterator.nextIndex();   // 下一个元素的索引
int prevIndex = listIterator.previousIndex(); // 前一个元素的索引

3.3 添加元素

在当前位置插入元素(不影响后续遍历):

listIterator.add("FOUR"); // 插入到 next() 返回元素之前,previous() 之后

3.4 替换元素

替换最近遍历的元素:

String next = listIterator.next();
if( "ONE".equals(next)) {
    listIterator.set("SWAPPED"); // 替换当前元素
}

⚠️ 限制set() 必须在最近一次 next()/previous() 调用后执行,且中间不能有 add()/remove() 操作。

3.5 完整示例

综合使用 ListIterator 的功能:

ListIterator<String> listIterator = items.listIterator();
// 正向遍历并替换
while(listIterator.hasNext()) {
    String next = listIterator.next();
    if("REPLACE ME".equals(next)) {
        listIterator.set("REPLACED");
    }
}
// 在末尾添加元素
listIterator.add("NEW");

// 反向遍历打印
while(listIterator.hasPrevious()) {
    System.out.println(listIterator.previous());
}

4. 总结

Iterator 提供了遍历时安全修改集合的能力,这是传统 for/while 循环难以实现的。其核心优势在于:

  • ✅ 遍历时安全删除元素
  • ✅ 代码解耦(遍历逻辑与业务逻辑分离)
  • ✅ ListIterator 支持双向操作和索引访问

在需要动态修改集合的场景下,Iterator 仍是 Java 中最优雅的解决方案之一。


« 上一篇: Java 虚引用详解