友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

17. 迭代器模式

17.1. 定义

根据 GoF 的著名著作 《设计模式》,迭代器模式的定义如下:

迭代器模式(Iterator)

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

— Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
《设计模式》

17.2. 类图

Diagram

迭代器模式 注: 结合 Java 中 Iterator 和 Iteratable ,具体分析一下迭代器在 Java 中的实现。另外,重点看看内迭代器和外迭代器之间的不同实现。

迭代器模式。

当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。

你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。

为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。

像IEnumerable接口也是为迭代器模式而准备的。不管如何,学习一下GoF的迭代器模式的基本结构,还是很有学习价值的。研究历史是为了更好地迎接未来。

Iterator迭代器抽象类

Aggregate聚集抽象类

ConcreteIterator具体迭代器类,继承Iterator

ConcreteAggregate具体聚集类继承Aggregate

当你需要对聚集有多种方式遍历时,可以考虑用迭代器模式

尽管我们不需要显式的引用迭代器,但系统本身还是通过迭代器来实现遍历的。总地来说,迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

代码 103. iterator/Aggregate.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package com.diguage.didp.iterator;

/**
 * Aggregate 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:35
 */
public abstract class Aggregate {
  public abstract Iterator createIterator();
}
代码 104. iterator/Client.java 类
 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
package com.diguage.didp.iterator;

/**
 * Client 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:35
 */
public class Client {
  public static void main(String[] args) {
    ConcreteAggregate aggregate = new ConcreteAggregate();
    int i = 0;
    aggregate.set(i++, "大鸟");
    aggregate.set(i++, "小菜");
    aggregate.set(i++, "行李");
    aggregate.set(i++, "老外");
    aggregate.set(i++, "公交内部员工");
    aggregate.set(i++, "小偷");

    Iterator iterator = new ConcreteIterator(aggregate);
    Object first = iterator.first();
    while (!iterator.isDone()) {
      System.out.printf("%s 请买车票!", iterator.currentItem());
      iterator.next();
    }
  }
}
代码 105. iterator/ConcreteAggregate.java 类
 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
package com.diguage.didp.iterator;

import java.util.ArrayList;
import java.util.List;

/**
 * ConcreteAggregate 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:35
 */
public class ConcreteAggregate extends Aggregate {
  private List<Object> items = new ArrayList<>();

  public Iterator createIterator() {
    return new ConcreteIterator(this);
  }

  public Object get(int index) {
    return items.get(index);
  }

  public void set(int index, Object item) {
    items.set(index, item);
  }

  public int count() {
    return items.size();
  }
}
代码 106. iterator/ConcreteIterator.java 类
 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
34
35
36
37
38
39
40
41
package com.diguage.didp.iterator;

/**
 * ConcreteIterator 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-23 09:09:49
 */
public class ConcreteIterator extends Iterator {
  private ConcreteAggregate aggregate;
  private int current = 0;

  public ConcreteIterator(ConcreteAggregate aggregate) {
    this.aggregate = aggregate;
  }

  @Override
  public Object first() {
    return aggregate.get(0);
  }

  @Override
  public Object next() {
    Object ret = null;
    current++;
    if (current < aggregate.count()) {
      ret = aggregate.get(current);
    }
    return ret;
  }

  @Override
  public boolean isDone() {
    return current >= aggregate.count();
  }

  @Override
  public Object currentItem() {
    return aggregate.get(current);
  }
}
代码 107. iterator/Iterator.java 类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.diguage.didp.iterator;

/**
 * Iterator 类
 *
 * @author D瓜哥, https://www.diguage.com/
 * @since 2017-05-19 17:53:35
 */
public abstract class Iterator {
  public abstract Object first();

  public abstract Object next();

  public abstract boolean isDone();

  public abstract Object currentItem();
}

17.3. 常见示例

  1. java.util.Iterator