我们讲了一个非常基础的 Serializable 接口,虽然在平时开发中,让我们直接手动进行 Java 对象的序列化场景非常少,更多是 框架、JVM 在帮我们做这个事儿,我们也介绍了 Java 序列化与 JSON 这样通用序列化格式的区别,以及各自的优势,今天我们继续介绍两个从名字和功能上乍一看都很相似的基础接口 -- Iterator 和 Iterable。
Java 的 Iterable 接口用来表示可迭代对象的集合,这意味着,实现 了 Iterable 接口的类可以迭代其元素。Java 里还有一个 Iterator 接口表示迭代器,迭代其实我们也可以简单地理解为遍历,是一个标准化遍历各类 Collection 容器里面的所有对象的接口。Java 的 Iterator 接口相当于是从语言本身支持迭代器这种设计模式,在文中介绍 Iterator 接口前,我们会先介绍一下迭代器设计模式的思想,以及使用这种设计模式能获得的收益。
Iterator 和 Iterable 这两个接口在命名上相似,新手学习时容易混淆,所以在这里把两者展开,梳理明白。本文大纲如下:
为避免混淆,Collection 和 集合指的是同类,而另外一个可以翻译成集合的Set 数据结构文中会直接用Set表示。
Iterator 接口
Iterator 接口的全限定名是 java.util.Iterator
,我们前面学习的 Java 集合框架里的各种容器也是 Iterator 接口的实现。java.util.Iterator
和它的实现类是 Java 语言内置提供的对迭代器模式的支持,这里我们先花点篇幅了解一下,到底什么是迭代器模式。
迭代器模式
迭代器模式用于遍历集合中的对象,很多语言里都内置了这种设计模式,迭代器模式的思想是将集合对象的遍历操作从集合类中拆分出来,放到迭代器实现类中,让两者的职责更单一。
迭代器模式属于 GoF 总结的 23 种设计模式中的行为型模式。在这种模式中,集合结构会提供一个迭代器。通过这个迭代器可以顺序遍历集合中的每个元素而不需要暴露其具体的实现。其结构,可以用下面这个 UML 类图表示:
- Iterator 接口: 这个接口会定义一些基础的操作函数,如
hasNext()
或getNext()
等。通过名称就可以看出,这些方法可以帮助我们执行遍历集合、重启迭代等操作。 - Collection 接口: 这个接口代表了要被遍历的集合。在这个接口里定义了一个
createIterator
方法,该方法会返回一个Iterator
的实例。 - Concrete Iterator:
Iterator
接口的具体实现类。 - Concrete Collection:
Collection
接口的具体实现类。
上面这个迭代器模式的结构中的各个角色映射到 Java 内置为我们提供的迭代器模式实现中来的话,iterator
接口就是一会儿要说到的java.util.iterator
接口,它定义了模式中迭代器的行为规范;collection
接口就是我们前面学过了集合框架的顶层接口java.util.collection
; Concrete Iterator
和Concrete Collection
即两个顶层接口的实现类则对应于前面几节学过的集合框架中的List
, Set