行为型模式之:
-
观察者模式(Observer) ✅ 重要程度:⭐️⭐️⭐️⭐️⭐️
-
迭代器模式(Iterator) ✅ 重要程度:⭐️⭐️⭐️⭐️⭐️
-
职责链模式(Chain of Responsibility)
重要程度:⭐️⭐️⭐️ -
命令模式(Command)
重要程度:⭐️⭐️⭐️⭐️ -
解释器模式(Interpreter)
重要程度:⭐️ -
中介者模式(Mediator)
重要程度:⭐️⭐️ -
备忘录模式(Memento)
重要程度:⭐️⭐️ -
状态模式(State)
重要程度:⭐️⭐️⭐️ -
策略模式(Strategy)
重要程度:⭐️⭐️⭐️⭐️ -
模板方法模式(Template Method)
重要程度:⭐️⭐️⭐️ -
访问者模式(Visitor)
重要程度:⭐️
上一节学习了观察者模式,并且横向扩展了应用场景,针对于EventBus,有一些优化场景没有进一步研究,这一节我们了解下什么是迭代器模式。
1.什么是迭代器模式
迭代器模式是一种行为设计模式,用于提供一种方法来顺序访问聚合对象中的各个元素,而不暴露其内部表示。它将遍历聚合对象的过程封装在一个迭代器对象中,客户端可以通过迭代器对象逐个访问聚合对象的元素,而无需了解其内部结构。
通俗点说,迭代器模式更像遍历工具类,用来遍历遍历集合对象。像list和arraylist具有不同的结构,那么迭代器的构造就是不同的。这样理解应该是没有问题的吧?Google了一下,大概是下面的样子
细分一下应该是一种数据结构对应一种迭代器
2.迭代器模式的实现
// 定义聚合接口
interface Aggregate {
Iterator createIterator();
}
// 定义具体聚合类
class ConcreteAggregate implements Aggregate {
private String[] elements;
public ConcreteAggregate(String[] elements) {
this.elements = elements;
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(elements);
}
}
// 定义迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 定义具体迭代器类
class ConcreteIterator implements Iterator {
private String[] elements;
private int position;
public ConcreteIterator(String[] elements) {
this.elements = elements;
this.position = 0;
}
@Override
public boolean hasNext() {
return position < elements.length;
}
@Override
public Object next() {
if (hasNext()) {
return elements[position++];
}
return null;
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
String[] data = {"A", "B", "C", "D", "E"};
Aggregate aggregate = new ConcreteAggregate(data);
Iterator iterator = aggregate.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
在这个例子中,Aggregate 定义了一个创建迭代器的接口,ConcreteAggregate 是具体的聚合类,实现了 Aggregate 接口,并创建了具体的迭代器 ConcreteIterator。ConcreteIterator 实现了迭代器接口 Iterator,用于遍历 ConcreteAggregate 中的元素。
客户端代码通过聚合对象的 createIterator() 方法获取迭代器对象,然后通过迭代器对象逐个访问聚合对象的元素。这样,客户端代码就不需要了解聚合对象的内部结构,而且可以灵活地遍历聚合对象的元素。
3.迭代器模式的使用场景
- 访问聚合对象的元素:当你需要访问一个聚合对象(如列表、集合、数组等)中的元素,但不希望暴露其内部表示时,迭代器模式非常有用。通过迭代器,客户端可以逐个访问聚合对象中的元素,而无需了解其内部结构。
- 封装遍历算法:迭代器模式将遍历聚合对象的过程封装在迭代器对象中,客户端无需编写遍历算法,只需使用迭代器提供的方法即可遍历元素。
- 支持多种遍历方式:迭代器模式允许聚合对象提供多种迭代方式,例如顺序遍历、倒序遍历、过滤遍历等,客户端可以根据需要选择合适的迭代器来遍历元素。
- 解耦客户端和聚合对象:迭代器模式可以将客户端代码与聚合对象的内部结构解耦,客户端只需要通过迭代器访问聚合对象的元素,而无需了解聚合对象的具体实现。
4.迭代器模式的实际使用
许多开源框架和库使用了迭代器模式来处理集合、列表和其他数据结构。以下是一些常见的开源框架和库,它们使用了迭代器模式:
- Java标准库中的集合类:Java中的
ArrayList、LinkedList、HashMap等集合类都实现了迭代器模式,使得用户可以通过迭代器遍历集合中的元素。 - Android开发中的
RecyclerView:RecyclerView是Android开发中常用的列表控件,它使用了迭代器模式来遍历列表中的数据项。通过RecyclerView.Adapter中的ViewHolder和onBindViewHolder()方法,可以将数据项绑定到列表项上。 - Guava库:Guava是Google开发的一个Java工具库,其中的
Lists、Sets、Maps等工具类提供了丰富的集合操作方法,并使用了迭代器模式来遍历集合中的元素。 - Apache Commons库:Apache Commons是Apache软件基金会提供的一个通用的Java工具库,其中的
CollectionUtils、IteratorUtils等工具类使用了迭代器模式来对集合进行操作和遍历。 - Spring框架:Spring框架中的许多模块都使用了迭代器模式,例如Spring Core模块中的
ListableBeanFactory接口和BeanDefinition接口,它们通过迭代器来遍历Spring容器中的Bean定义。
5.优缺点
优点:
- 分离了集合对象的遍历行为:迭代器模式将集合对象的遍历行为封装到迭代器中,使得集合对象和遍历算法彼此独立,可以独立地改变它们而不会相互影响。
- 简化了集合类接口:使用迭代器模式后,集合类不再需要暴露自己的内部结构,只需提供一个迭代器接口,使得集合类的设计更加简洁和灵活。
- 支持多种遍历方式:迭代器模式可以为同一个集合类提供多种不同的遍历方式,而且用户可以根据需要选择不同的迭代器来遍历集合,提高了灵活性和可复用性。
- 增强了扩展性:通过定义不同类型的迭代器,可以实现对不同类型集合的遍历,而且可以方便地扩展和增加新的迭代器类型。
缺点:
- 增加了系统的复杂性:引入迭代器模式会增加系统中的类和对象数量,增加了系统的复杂性和理解难度。
- 对于某些集合类型效率较低:在某些特定的集合类型中,如链表等,使用迭代器模式可能会导致遍历效率较低,因为每次迭代都需要进行对象的访问和方法调用。
6.怎么在迭代器中删除或者增加元素呢?
对于增加和删除元素的机制,一般情况下,如果在遍历过程中对集合进行了增加或删除操作,可能会影响到迭代器的行为和遍历结果。为了避免这种情况下的并发修改异常,可以采取以下两种常见的机制:
- 快照机制:在迭代器开始遍历之前,先创建集合的一个快照(副本),然后对快照进行遍历操作,这样即使原集合发生了变化,也不会影响遍历结果(
快照机制也可以参照数据的结构)。 - 异常机制:如果在迭代过程中发现集合发生了变化,可以抛出一个并发修改异常,通知用户集合发生了改变,遍历可能会产生不确定的结果,
一般是和数据库保持数据一致性一样,通过记录修改的次数,或者时间戳。