java-Iterator

每日一言

如果什么都不做,那就什么也不会开始。

——《元气少女缘结神》

什么是Iterator

Iterator 迭代器是Java集合Collection框架中的一种机制,是一种用于遍历集合如(列表,集合,映射等实现Collection接口)的类。

原因是 Collection 接口继承了 java.lang.Iterable 接口。Iterable 接口定义了一个核心方法 iterator(),该方法返回一个 Iterator 对象。

因此,任何实现了 Collection 接口的类(如 ArrayList, LinkedList, HashSet, TreeSet 等)都必须提供 iterator() 方法的实现,从而允许你获取一个用于遍历其元素的 Iterator

使用Iteartor遍历集合

Iterator 类位于java.util包中,使用前需要引入:

1
import java.util.Ierator;

迭代器接口定义了几个方法:最常用的是以下三个:

  • next()-返回迭代器的下一个元素,并将迭代器的指针移到下一个位置
  • hashNext()-用于判断集合中是否还有下一个元素可以访问
  • remove()-从集合中删除迭代器最后访问的元素

获取Iterator

通过调用Iterator()方法获取Iterator对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
public static void main(String[] args) {

// 创建集合
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");

// 获取迭代器
Iterator<String> it = sites.iterator();

System.out.println(it); // 输出迭代器对象
//it.remove(); //抛出异常

// 输出集合中的第一个元素
System.out.println(it.next());
it.remove(); // 删除第一个元素,无返回值
}
}

输出为:

1
2
java.util.ArrayList$Itr@4617c264
Google

循环集合元素

让迭代器 it 逐个返回集合中所有元素最简单的方法是使用 while 循环:

1
2
3
while(it.hasNext()) {
System.out.println(it.next());
}

For-each循环

Java 中的 for-each 循环(也称为增强型 for 循环)是一种语法糖(syntactic sugar),它简化了遍历数组或实现了 java.lang.Iterable 接口的集合(如 Collection)的过程。编译器会在编译时将其转换为等效的使用 Iterator 或索引访问的代码。

1. 遍历实现了Collection接口的对象

  • 当 for-each 循环用于遍历实现了 Iterable 接口的对象时(例如 ArrayList, HashSet 等),编译器会将其转换为使用 Iterator 的代码。

原始代码:

1
2
3
4
5
List<String> list = new ArrayList<>();
// ... 添加元素 ...
for (String element : list) {
System.out.println(element);
}

编译后的代码:

1
2
3
4
5
6
7
List<String> list = new ArrayList<>();
// ... 添加元素 ...
Iterator<String> iterator = list.iterator(); // 1. 获取 Iterator
while (iterator.hasNext()) { // 2. 使用 hasNext() 判断
String element = iterator.next(); // 3. 使用 next() 获取元素
System.out.println(element); // 4. 执行循环体
}

我们看一个例子以便加深我们对于Iterator的理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
public static void main(String[] args) {
// 创建集合
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");

for(String site : sites) {
if(site.equals("Runoob")) {
site = "Runoob.com";
}
}

for(String site : sites) {
System.out.println(site);
}
}
}

输出:

1
2
3
4
Google
Runoob
Taobao
Zhihu

我们对于Runoob的修改并没有生效,这里我们解释一下原因:

  • Iterator类指向的为集合中元素的地址。
  • String类具有不可变性
  • Iterator.next()方法返回元素的引用。

1745830634662

由于String的不可变性,没有修改源集合中元素地址中的值,而是将引用指向了另一个地址:

1745830721544

如果我们将String修改为StringBuffer类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 引入 ArrayList 和 Iterator 类
import java.util.ArrayList;
import java.util.Iterator; // Iterator 未在此示例中使用,但保留 import

public class RunoobTest {
public static void main(String[] args) {

// 创建集合,使用 StringBuffer
ArrayList<StringBuffer> sites = new ArrayList<StringBuffer>();
sites.add(new StringBuffer("Google"));
sites.add(new StringBuffer("Runoob"));
sites.add(new StringBuffer("Taobao"));
sites.add(new StringBuffer("Zhihu"));

// 遍历并尝试修改 StringBuffer 对象的内容
for(StringBuffer site : sites) {
// 比较 StringBuffer 的内容
if(site.toString().equals("Runoob")) {
// 修改 StringBuffer 对象的内容
site.delete(0, site.length()).append("Runoob.com");
}
}

// 打印修改后的列表内容
for(StringBuffer site : sites) {
System.out.println(site); // 会自动调用 StringBuffer 的 toString()
}
}
}

我们则可以直接修改地址中的内容,从而达到修改集合中元素的效果,运行结果:

1
2
3
4
Google
Runoob.com
Taobao
Zhihu

2. 遍历数组

当 for-each 循环用于遍历数组时,编译器会将其转换为使用传统索引访问的 for 循环。

原始代码:

1
2
3
4
String[] array = {"a", "b", "c"};
for (String element : array) {
System.out.println(element);
}

编译后的代码:

1
2
3
4
5
String[] array = {"a", "b", "c"};
for (int i = 0; i < array.length; i++) { // 1. 使用索引循环
String element = array[i]; // 2. 通过索引访问元素
System.out.println(element); // 3. 执行循环体
}

遍历数组时哪怕直接使用索引来访问数组,但是在For-each的遍历中,仍然创建一个引用来访问变量。保证了使用for-each循环时的统一性。


java-Iterator
http://blog.ulna520.com/2025/04/28/java-Iterator_20250428_154340/
Veröffentlicht am
April 28, 2025
Urheberrechtshinweis