迭代器模式


迭代器模式(Iterator Pattern)又称为游标(Cursor)模式,是最常被使用的几个模式之一,被广泛地应用到 Java 的 API 中。例如,Java 的集合(Collection)框架中,就广泛使用迭代器来遍历集合中的元素。

定义

迭代器模式的英文定义如下:

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
意思是:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。
迭代器是为容器服务的,容器是指用来容纳其他对象的对象,例如,Collection 集合类型、Set 类等。

组成角色

迭代器模式有以下 4 个角色:

  • 抽象迭代器(Iterator)角色:该角色负责定义访问和遍历元素的接口;
  • 具体迭代器(Concrete Iterator)角色:该角色实现 Iterator 接口,完成容器元素的遍历;
  • 抽象聚集(Aggregate)角色:该角色提供创建迭代器角色的接口;
  • 具体聚集(Concrete Aggregate)角色:该角色实现抽象聚集接口,创建出容纳迭代器的对象。
    角色之间的关系,如下图所示:

迭代器模式代码实现

抽象迭代器

interface Iterator {
    public Object next();
    public boolean hasNext();
}

具体迭代器

class ConcreteIterator implements Iterator {
    private ConcreteAggregate aggregate;
    private int index;
    private int size;
    public ConcreteIterator(ConcreteAggregate aggregate) {
        this.aggregate = aggregate;
        this.index = 0;
        this.size = aggregate.size();
    }
    // 是否有下一个元素
    @Override
    public boolean hasNext() {
        return index < size;
    }
    // 返回下一个元素
    @Override
    public Object next() {
        if (index < size) {
            return aggregate.getElement(index++);
        }
        return null;
    }
}

抽象聚集

interface Aggregate {
    public void add(Object obj);
    public Iterator createIterator();
}

具体聚集

class ConcreteAggregate implements Aggregate {
    // 私有存储容器
    private Vector vector = new Vector();
    // 添加元素
    @Override
    public void add(Object obj) {
        this.vector.add(obj);
    }
    // 根据下标获取元素
    public Object getElement(int index) {
        return vector.get(index);
    }
    // 获取集合长度
    public int size() {
        return vector.size();
    }
    // 创建迭代器
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        // 定义聚族对象
        Aggregate aggregate = new ConcreteAggregate();
        aggregate.add("Java");
        aggregate.add("MySQL");
        aggregate.add("Spring");
        // 遍历
        Iterator iterator = aggregate.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

程序执行结果:

Java

MySQL

Spring

优缺点

迭代器模式的优点:

  • 迭代器模式将数据存储和数据遍历的职责进行分离;
  • 迭代器模式简化了遍历容器元素的操作;
  • 迭代器模式使不同的容器,具备一个统一的遍历接口;
  • 迭代器模式封装了遍历算法,使算法独立于聚集角色,调用者无须知道聚集对象的类型,即使聚集对象的类型发生变化,也不会影响遍历过程。
    迭代器模式的缺点:
  • 由于迭代器模式将数据存储和数据遍历的职责进行分离,如果增加新的聚合类,同时需要增加与之相对应的迭代器类,这使得类的个数会成对增加,在某种程度上来说增加了系统的复杂性。

应用场景

迭代器的应用很广泛,已经发展成为程序开发中最基础的工具类了。在 Java 语言中,从 JDK 1.2 开始,增加了 java.util.Iterator 接口,并将 Iterator 应用到各个聚集类(Collection)中,如 ArrayList、Vector、Stack、HashSet 等集合类都实现了 iterator() 方法,返回一个迭代器 Iterator,用于对集合中的元素进行遍历。这使我们在项目中无须在独立地写迭代器,直接使用即可,这样既轻松又便捷。

注意:要尽可能地使用编程语言自身提供的迭代器,而非自己写的迭代器。

使用实例

下面将会使用 Java API 提供的迭代器模式,演示迭代器的具体使用。

public class Lesson19 {
    public static void main(String[] args) {
        // 调用迭代器应用示例
        new IteratorUseDemo().doIterator();
    }
}
/**
 * 迭代器应用——演示示例
 */
class IteratorUseDemo {
    void doIterator() {
        // 定义 Vector 集合
        Vector vector = new Vector();
        vector.add("Vector 1");
        vector.add("Vector 2");
        vector.add("Vector 3");
        // 定义 ArrayList 集合
        ArrayList list = new ArrayList();
        list.add("ArrayList 1");
        list.add("ArrayList 2");
        list.add("ArrayList 3");
        // 使用迭代器循环 Vector
        java.util.Iterator vIterator = vector.iterator();
        while (vIterator.hasNext()) {
            System.out.println(vIterator.next());
        }
        // 使用迭代器循环 ArrayList
        java.util.Iterator lIterator = list.iterator();
        while (lIterator.hasNext()) {
            System.out.println(lIterator.next());
        }
    }
}

程序执行结果:

Vector 1

Vector 2

Vector 3

ArrayList 1

ArrayList 2

ArrayList 3

从上面示例可以看出,集合都可以通过 iterator() 方法,获得统一的迭代器对象 java.util.Iterator,然后进行循环遍历。

总结

迭代器模式是最常用的设计模式之一,已经被广泛应用到 Java 的 API 中,比如在 Java 的集合中,使用 iterator() 方法就可以获得统一的迭代器对象 java.util.Iterator,使用这个对象就可以很方便地实现集合的遍历功能。迭代器包含四个角色(抽象迭代器、具体迭代器、抽象聚集和具体聚集)和两个重要的方法:hasNext() 方法用来判断是否还有下一个未遍历的元素,next() 方法用来获取此次遍历的对象。要注意的是,如果编程语言中已经提供了内置的迭代器,并且能满足现有需求的情况下,开发者就不必自己再写迭代器了。


Author: Re:0
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Re:0 !
 Previous
观察者模式 观察者模式
定义观察者模式(Observer Pattern)也称发布订阅模式。
2022-03-12
Next 
解释器模式 解释器模式
解释器模式,这个模式我觉得是这些模式中最不好理解的模式,解释器模式是用来干啥的呢?比如说我们有一段英文或者一段公式,我们需要知道其中表达的意思到底是啥?(假如我们起初并不理解)也就是说,我们需要一个”解释人”,该角色就是我们的联络官或者叫做
2022-03-11
  TOC