参考源
https://www.bilibili.com/video/BV1u3411P7Na?p=25&vd_source=299f4bc123b19e7d6f66fefd8f124a03
迭代器模式(Iterator Pattern)属于行为型模式
概述
迭代器模式是 Java 中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,而不需要知道集合对象的底层表示。
迭代器是学习 Java 语言的基础,没有迭代器,集合类的遍历就成了问题,正是因为有迭代器的存在,才能更加优雅的使用 foreach 语法。
Java 中的增强 for 循环是使用迭代器实现的:
- List
list = Arrays.asList("AAA", "BBB", "CCC"); - // 使用 foreach 语法糖进行迭代,依次获取每一个元素
- for (String s : list) {
-
- // 打印元素
- System.out.println(s);
- }
编译之后的代码如下:
- List
list = Arrays.asList("AAA", "BBB", "CCC"); - // 这里本质是通过 List 生成的迭代器来遍历每个元素的
- Iterator var2 = list.iterator();
- // 判断是否还有元素可以迭代,没有就返回false
- while(var2.hasNext()) {
-
- // 通过 next 方法得到下一个元素,每调用一次,迭代器会向后移动一位
- String s = (String)var2.next();
- // 打印元素
- System.out.println(s);
- }
可以看到,当使用迭代器对 List 进行遍历时,实际上就像是在操作一个指向列表头部的指针,通过不断向后移动指针来依次获取所指向的元素。


代码实现
这里依照 JDK 提供的迭代器接口(JDK 已经定义好了一个迭代器的具体相关操作接口),也来设计一个迭代器:
1、定义数组集合
- /**
- * 数组集合
- * 实现 Iterable 接口表示此类是支持迭代的
- */
- public class ArrayCollection
implements Iterable { -
- /**
- * 使用数组来存放数据
- */
- private final T[] array;
-
- /**
- * 构造器私有,自己用
- * @param array 数组
- */
- private ArrayCollection(T[] array) {
- this.array = array;
- }
-
- /**
- * 使用静态方法获取对象
- * @param array 数组
- * @return 数组集合对象
- * @param
实体类 - */
- public static
ArrayCollection of(T[] array) { - return new ArrayCollection<>(array);
- }
-
- /**
- * 实现 iterator 方法,此方法会返回一个迭代器,用于迭代我们集合中的元素
- * @return 迭代器
- */
- @Override
- public Iterator
iterator() { - return new ArrayIterator();
- }
-
- /**
- * 这里自定义 ArrayIterator,注意别用静态,需要使用对象中存放的数组
- */
- public class ArrayIterator implements Iterator
{ -
- // 这里通过指针表示当前的迭代位置
- private int index = 0;
-
- /**
- * 判断是否还有下一个元素
- * @return 结果
- */
- @Override
- public boolean hasNext() {
-
- // 如果指针大于或等于数组最大长度,就不能再继续了
- return index < array.length;
- }
-
- /**
- * 返回当前指针位置的元素并向后移动一位
- * @return
- */
- @Override
- public T next() {
-
- // 正常返回对应位置的元素,并将指针自增
- return array[index++];
- }
- }
-
- }
2、调用
- // 定义数组
- String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
- // 使用数组集合处理数组
- ArrayCollection
collection = ArrayCollection.of(arr); - // 使用 foreach 语法糖遍历,最后还是会变成迭代器调用
- for (String s : collection) {
- System.out.println(s);
- }
编译后的代码为:
- String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
- ArrayCollection
collection = ArrayCollection.of(arr); - // 首先获取迭代器,实际上就是调用我们实现的 iterator 方法
- Iterator var3 = collection.iterator();
-
- while(var3.hasNext()) {
- // 使用 next() 方法不断向下获取
- String s = (String)var3.next();
- System.out.println(s);
- }
输出结果为:
- AAA
- BBB
- CCC
- DDD
这样就实现了自定义迭代器来遍历数组。
优缺点
优点
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合类。
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景
1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。
