首页 > 编程笔记 > Java笔记 阅读:2

迭代器模式(java实现,附带实例)

迭代器模式是《设计模式》一书中的一个关键模式,可以抽象成一个指向当前位置的光标或指针。

由于数组很早就成为一种常用的数据结构,而我们在处理这种结构时经常需要管理当前处理到的位置,因此业界很快就提出了迭代器模式。

迭代器模式让我们能够向用户提供一种清晰的遍历方式,以供其遍历某一系列的对象,同时又不需要公布或暴露这些对象的内部细节。用户可以使用迭代函数从一个元素移动到下一个元素。

迭代器模式在JDK中的运用

在 java.base 模块中有好几个地方实现了迭代器模式。

第一个地方位于 Java 集合框架里,也就是 java.util 包中。这个包的 Iterator 接口用的是迭代器模式,该接口让用户能够遍历某集合内的各个元素,而不用知晓这些元素具体属于哪种类型,也无须关注它们究竟放在什么样的集合里面。

还有一个地方是 BaseStream 接口以及该接口的 iterator 方法。这个接口与 Iterator 接口都在 java.base 模块里,但是所属的包与前者不同,它位于 java.util.stream 包,也就是提供 Stream API 的那个包中。该接口的 iterator 方法提供一个迭代器,用来遍历 Stream 中的各个元素,这是一个最终操作(terminal operation),它后面不能拼接别的 Stream 操作。

迭代器模式实例演示

每种车都有一些共同的部件,我们将这些部件抽象到一种标准的车辆中。下面这个例子演示了如何使用迭代器模式来遍历这种标准车辆中的各个部件。

【实例】用迭代器模式遍历车中的各个部件。
public static void main(String[] args) {
    System.out.println("Iterator Pattern, vehicle parts");

    var standardVehicle = new StandardVehicle();
    for (PartsIterator part = standardVehicle.getParts();
         part.hasNext();) {
        var vehiclePart = part.next();
        System.out.println("VehiclePart name:" + vehiclePart.name());
    }
}
程序输出结果如下:

Iterator Pattern, vehicle parts
VehiclePart name:engine
VehiclePart name:breaks
VehiclePart name:navigation

表示车辆的 Vehicle 接口定义了一个用来获取迭代器的 getParts() 方法,该方法返回下面这样一种迭代器,使得用户能够通过该迭代器遍历车辆中的各个部件(参见下面的范例)。

【实例】程序可以用不同的方法来实现迭代器。
interface PartsIterator {
    boolean hasNext();
    VehiclePart next();
}
无论怎么实现该迭代器,用户都可以通过 PartsIterator 接口的 next() 方法逐个处理车辆中的各个部件。

我们这里采用的办法是在具体的车辆类(也就是表示标准车辆的 StandardVehicle 类)里设计名为 VehiclePartsIterator 的嵌套类,让这个嵌套类实现 PartsIterator 迭代器接口(参见下面的范例)。

【实例】在具体的车辆类里以嵌套类的形式实现通用的PartsIterator迭代器接口。
sealed interface Vehicle permits StandardVehicle {
    PartsIterator getParts();
}

final class StandardVehicle implements Vehicle {
    private final String[] vehiclePartsNames = {"engine", "breaks", "navigation"};

    private class VehiclePartsIterator implements PartsIterator {
        // ...
    }

    @Override
    // ...
}
程序给用户提供了一种清晰而方便的迭代方式,并且定义了一个易于扩展的框架,让我们以后能够在车辆里轻松地添加其他一些部件(这些部件可以是 VehiclePart 类型,也可以是其子类),用户无须大幅修改代码,即可遍历并处理我们新添加的部件(参见下图)。


图 1 用UML类图演示如何提供一种能够遍历车辆中各个部件的迭代器

总结

迭代器模式的强大之处在于,它能够以一种相当通用的方式来实现,让用户不用关注需要迭代的这些元素具体是什么类型。

用户只需使用迭代器来遍历这些元素就好,而无须关注这些元素在程序里究竟是用什么样的方式来表示的。

相关文章