每日一言
如果什么都不做,那就什么也不会开始。
——《元气少女缘结神》
什么是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
| 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);
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(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); }
|
我们看一个例子以便加深我们对于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
| 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()方法返回元素的引用。

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

如果我们将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
| import java.util.ArrayList; import java.util.Iterator;
public class RunoobTest { public static void main(String[] args) {
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"));
for(StringBuffer site : sites) { if(site.toString().equals("Runoob")) { site.delete(0, site.length()).append("Runoob.com"); } }
for(StringBuffer site : sites) { System.out.println(site); } } }
|
我们则可以直接修改地址中的内容,从而达到修改集合中元素的效果,运行结果:
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++) { String element = array[i]; System.out.println(element); }
|
遍历数组时哪怕直接使用索引来访问数组,但是在For-each的遍历中,仍然创建一个引用来访问变量。保证了使用for-each循环时的统一性。