Iterator 迭代器


十二月了,今年要结束了。

这周学习 Java 的迭代器原理,迭代器是各编程语言都会有的设计,这里只关注 Java 的实现。


迭代的意思是重复地同一样事,比如写一个 for 循环,每层循环内部执行一些逻辑,就是在迭代。

迭代器,用字面上的意思去理解,就是专注做迭代这件事的工具,即这个工具持续地、专注地做一件重复的事情。

实际上,编程中的迭代器,做的那件重复的事情是有所特指的,专指访问容器中的元素。例如一个列表(list)中有十个元素,使用迭代器可以重复性地逐个访问这十个元素,就跟写一个 for 循环一样。

容器分很多种,array 是容器、list 是容器、set 是容器、map 是容器,如果你的目的是遍历某一种容器,你应该写不一样的 for 循环(而且有些容器你无法通过 for 循环来遍历),但是如果你使用迭代器,你可以用同一种逻辑来遍历任何一种容器。迭代器的好处在于,你可以无视容器的类型,用同样的逻辑来处理它们。

所以我觉得吧,迭代器也可以简单粗暴地称为遍历器。

再体会一下维基百科对于迭代器的解释:

迭代器(iterator)是可在容器物件(container,例如链表或阵列)上遍访的介面,设计人员无需关心容器物件的内存分配的实现细节。


Java 的迭代器是 Iterator 类,是一个从 JDK 1.2 起就存在的元老设计。

Iterator 类是一个接口,规范了迭代器的基本规则。它在 1.2 版本时只有三个方法,在 1.5 版本时开始支持泛型,在 1.8 版本时引入函数式编程。不过在学习时,只关注 1.2 版本的最初那三个方法即可。

以下是 Iterator 类的三个方法:

1
2
3
4
5
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
  • boolean hasNext():是否有下一个元素(即是不是还没有遍历完容器)
  • Object next():取出来下一个元素并返回,可以使用泛型来指定类,当执行完该方法,迭代器将自动挪到下一个元素
  • void remove():删除上一个元素(即删除刚刚越过的那个元素)

由于这三个方法非常简单,含义也很清晰,在此只给出一段代码,表个意思。

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
30
31
32
33
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println("list初始值为:" + list);
// list初始值为:[1, 2, 3]


Iterator<Integer> iterator = list.iterator();
Integer next1 = iterator.next();
System.out.println("第一次执行next()方法:" + next1);
// 第一次执行next()方法:1


Integer next2 = iterator.next();
System.out.println("第二次执行next()方法:" + next2);
// 第二次执行next()方法:2


iterator.remove();
System.out.println("执行完remove()方法后,此时的列表值为:" + list);
// 执行完remove()方法后,此时的列表值为:[1, 3]


boolean hasNext1 = iterator.hasNext();
System.out.println("此时是否有下一个元素:" + hasNext1);
// 此时是否有下一个元素:true


Integer next3 = iterator.next();
boolean hasNext2 = iterator.hasNext();
System.out.println("此时是否有下一个元素:" + hasNext2);
// 此时是否有下一个元素:false

这周又是懒得不行,暂且写到这里。下周开始看各容器的迭代器实现源码,进入源码的世界。