什么是 Iterator?
Iterator 是一个接口,它提供了一种统一的方式来遍历集合(Collection)中的元素,而无需关心集合底层的具体实现(是 ArrayList、LinkedList 还是 HashSet)。

你可以把它想象成一个指向集合元素的光标,它总在元素之间移动,告诉你当前的位置,并允许你获取下一个元素。
Iterator 的核心方法
Iterator 接口主要定义了三个方法:
| 方法名 | 描述 |
|---|---|
boolean hasNext() |
判断当前位置的后面是否还有元素,如果有,返回 true;否则返回 false。 |
E next() |
获取当前位置的元素,并将迭代器的光标向后移动一位。 |
void remove() |
删除迭代器最后返回的那个元素,这是一个可选操作,并非所有集合都支持。 |
注意:调用
next()之前,必须先调用hasNext()进行判断,如果直接调用next()而没有元素了,会抛出NoSuchElementException异常。
如何获取和使用 Iterator?
我们通过集合对象的 iterator() 方法来获取其对应的 Iterator 实例。

下面我们通过一个完整的例子来演示如何使用 Iterator 遍历 ArrayList。
示例代码:基本遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
// 1. 创建一个 List 集合
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Mango");
System.out.println("原始集合: " + fruits);
// 2. 通过 iterator() 方法获取迭代器
Iterator<String> iterator = fruits.iterator();
// 3. 使用 while 循环和迭代器遍历集合
System.out.println("\n使用 Iterator 遍历集合:");
while (iterator.hasNext()) {
// 4. 获取当前元素
String fruit = iterator.next();
System.out.println(fruit);
// 你可以在这里对元素进行操作,比如判断
if ("Orange".equals(fruit)) {
System.out.println(" -> 我最喜欢的水果是橙子!");
}
}
System.out.println("\n遍历完成后的集合: " + fruits);
}
}
输出结果:
原始集合: [Apple, Banana, Orange, Mango]
使用 Iterator 遍历集合:
Apple
Banana
Orange
-> 我最喜欢的水果是橙子!
Mango
遍历完成后的集合: [Apple, Banana, Orange, Mango]
Iterator 的 remove() 方法
remove() 方法是一个强大的功能,它允许你在遍历时安全地删除元素,它删除的是上一次调用 next() 方法返回的元素。
示例代码:遍历时删除元素
假设我们要从集合中删除所有以 "A" 开头的元素。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorRemoveExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Amy");
names.add("David");
names.add("Alex");
System.out.println("删除前的集合: " + names);
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if (name.startsWith("A")) {
// 使用迭代器的 remove 方法删除元素
iterator.remove();
}
}
System.out.println("删除后的集合: " + names);
}
}
输出结果:
删除前的集合: [Alice, Bob, Amy, David, Alex]
删除后的集合: [Bob, David]
⚠️ 重要警告:
- 不能使用集合的
remove()方法:如果在迭代过程中使用集合自身的remove()方法(如list.remove("Alice")),会抛出ConcurrentModificationException(并发修改异常),这是因为迭代器在遍历时会维护一个“预期修改计数”,而集合的remove()方法会改变这个计数,导致迭代器检测到数据被“意外”修改。remove()的时机:remove()必须紧跟在next()之后调用,如果在没有调用next()或已经调用了next()但又调用了下一次next()之后调用remove(),同样会抛出IllegalStateException。
Iterator vs. for-each 循环
在现代 Java 开发中,我们更常用 for-each 循环(也称为增强 for 循环)来遍历集合或数组。
for-each 循环示例
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
System.out.println("使用 for-each 循环遍历:");
for (String fruit : fruits) {
System.out.println(fruit);
}
for-each 循环的本质
for-each 循环只是 Iterator 的一个语法糖(Syntactic Sugar),编译器在后台会自动将 for-each 循环转换成使用 Iterator 的 while 循环。
下面两段代码在编译后是等价的:
// 代码 1: for-each 循环
for (String fruit : fruits) {
// do something
}
// 代码 2: 编译器转换后的等价代码
for (Iterator<String> i = fruits.iterator(); i.hasNext();) {
String fruit = i.next();
// do something
}
Iterator vs. ListIterator
ListIterator 是 Iterator 的一个子接口,专门用于遍历 List 集合,它提供了比 Iterator 更强大的功能:
| 特性 | Iterator |
ListIterator |
|---|---|---|
| 适用范围 | 所有 Collection |
仅 List |
| 遍历方向 | 只能向后 | 可以向前,也可以向后 |
| 获取索引 | 不支持 | 支持 nextIndex() 和 previousIndex() |
| 添加元素 | 不支持 | 支持 add(E e) 方法 |
| 修改元素 | 不支持 | 支持 set(E e) 方法 |
ListIterator 示例
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
ListIterator<String> listIterator = names.listIterator();
System.out.println("向后遍历:");
while (listIterator.hasNext()) {
System.out.println(listIterator.nextIndex() + ": " + listIterator.next());
}
System.out.println("\n向前遍历:");
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previousIndex() + ": " + listIterator.previous());
}
System.out.println("\n在 'B' 后插入 'X'");
// 将光标移动到 'B' 的后面
listIterator.next(); // A
listIterator.next(); // B
listIterator.add("X"); // 在 B 后面插入 X
System.out.println("插入后的集合: " + names);
}
}
输出结果:
向后遍历:
0: A
1: B
2: C
向前遍历:
2: C
1: B
0: A
在 'B' 后插入 'X'
插入后的集合: [A, B, X, C]
总结与最佳实践
-
何时使用
Iterator?- 当你需要在遍历过程中安全地删除元素时,必须使用
Iterator的remove()方法。 - 当你需要双向遍历(
ListIterator)或在遍历时添加/修改元素时,使用ListIterator。
- 当你需要在遍历过程中安全地删除元素时,必须使用
-
何时使用
for-each循环?- 在绝大多数情况下,
for-each循环是遍历集合或数组的首选和最佳方式,因为它代码更简洁、可读性更高,并且能避免ConcurrentModificationException。 - 只在你需要
Iterator的特殊功能(如remove、add、双向遍历)时,才显式地使用Iterator或ListIterator。
- 在绝大多数情况下,
-
核心思想:
Iterator提供了解耦:遍历逻辑与集合的具体实现分离开,使得遍历算法可以适用于任何集合。- 它是 Java 集合框架“面向接口编程”思想的完美体现。
