Java - GoF设计模式详解17(迭代器模式)
作者:hangge | 2023-06-16 08:50
十七、迭代器模式
1,基本介绍
(1)迭代器模式(Iterator)提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
(2)该模式中包含的角色及其职责如下:
- 抽象迭代器(Iterator):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法。
- 具体迭代器(Concrete Iterator):它实现了抽象迭代器的接口,并保存遍历当前位置的状态。
- 抽象聚合类(Aggregate):它声明了创建相应迭代器对象的接口,即 createIterator() 方法。
- 具体聚合类(Concrete Aggregate):它实现了抽象聚合类的 createIterator() 方法,返回一个与该聚合对象相关的具体迭代器 Concrete Iterator 实例。

2,使用样例
(1)下面通过样例演示迭代器模式的使用。首先定义迭代器接口 Iterator,在该接口中规范了迭代器应该实现的方法。
// 迭代器接口
public interface Iterator<E> {
// 判断在迭代器中是否还有元素
boolean hasNext();
// 访问迭代器中的下一个元素
E next();
}
(2)接着定义迭代器接口 Iterator 的具体实现类 ConcreteIterator,其中定义了 list 用于访问集合中的数据,index 用于记录当前迭代器遍历到的元素位置,同时实现了在 Iterator 接口中定义的方法,以完成具体的迭代器需要实现的基础功能。
// 具体迭代器
public class ConcreteIterator<E> implements Iterator<E> {
// 集合数据
private List<E> list;
//记录当前迭代器遍历到的元素位置
private int index;
public ConcreteIterator(List<E> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public E next() {
return list.get(index++);
}
}
(3)然后定义集合接口 Aggregate,用于制定集合操作的规范。在该接口中定义了 iterator() 用于集合接口的遍历。
// 集合接口
public interface Aggregate<E> {
// 获取迭代器
Iterator<E> iterator();
}
(4)接着定义 Aggregate 接口实现类 ConcreteAggregate,ConcreteAggregate 类用于存储具体的数据并实现数据操作方法,其中,list 用于存储数据,iterator() 用于构造集合迭代器。
// 具体集合
public class ConcreteAggregate<E> implements Aggregate<E> {
// 集合数据
private List<E> list;
public ConcreteAggregate(List<E> list) {
this.list = list;
}
@Override
public Iterator<E> iterator() {
return new ConcreteIterator<>(list);
}
}
(5)最后测试一下迭代器的使用,首先需要定义一个集合并向集合中加入数据,然后获取集合的 Iterator 迭代器并通过循环遍历集合中的数据。
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("hangge", "google", "baidu");
// 创建集合对象
Aggregate<String> aggregate = new ConcreteAggregate<>(list);
// 创建迭代器
Iterator<String> iterator = aggregate.iterator();
// 使用迭代器遍历元素
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
附一:JDK 中的迭代器模式
(1)Java 标准库中的迭代器模式用在了 java.util.Iterator 接口和 java.util.Enumeration 接口中。大多数的集合类(例如 java.util.List、java.util.Set 和 java.util.Map)都提供了 iterator() 方法来返回一个 java.util.Iterator 对象,用于遍历集合中的元素。
关于集合遍历更详细的介绍,可以参考我之前写的另一篇文章:
(2)比如我们可以使用以下代码遍历 java.util.List 中的元素:
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hangge");
list.add("google");
list.add("baidu");
// 获取迭代器
Iterator<String> iterator = list.iterator();
// 使用迭代器遍历元素
while (iterator.hasNext()) {
String s = iterator.next();
System.out.println(s);
}
}
}
附二:Spring 中的迭代器模式
(1)Spring Framework 在内部使用了迭代器模式,在一些地方使用了 java.util.Iterator 接口,这个接口提供了一种遍历集合的方法。比如 ConfigurableListableBeanFactory 类有一个 getBeanNamesIterator() 方法,该方法返回一个 Iterator<String>,可以用来遍历所有已注册的 bean 的名称。下面是一个简单的样例:
@RestController
public class HelloController {
@Autowired
private ConfigurableListableBeanFactory beanFactory;
@GetMapping("/hello")
public String hello() {
String result = "";
Iterator<String> iterator = beanFactory.getBeanNamesIterator();
while (iterator.hasNext()) {
String beanName = iterator.next();
result += beanName + "<br>";
}
return result;
}
}
(2)项目启动后,使用浏览器访问 hello 即可看得到 Spring 容器中所有注册的 bean 的名字:
全部评论(0)