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)