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 中最优雅的解决方案之一。