一.介绍
迭代器模式(Iterator Pattern)属于行为型模式。提供一个对象来顺序访问容器对象中的一系列数据,目的是在不暴露容器对象内部结构的情况下,让外部代码使用统一的API透明地访问容器的内部数据
二.UML类图
三.示意代码
业务代码
//抽象迭代器
public interface Iterator {
boolean hasNext();
Object next();
}
//抽象容器
interface ICollection {
void add(Object o);
int size();
Iterator iterator();
}
//具体容器
class IArrayList implements ICollection {
private int size;
private Object[] elementData = new Object[2];
@Override
public void add(Object o) {
if (size >= elementData.length) {
elementData = Arrays.copyOf(elementData, elementData.length << 1);
}
elementData[size++] = o;
}
@Override
public int size() {
return size;
}
@Override
public Iterator iterator() {
return new ArrayListIterator();
}
//具体迭代器
private class ArrayListIterator implements Iterator {
private int pos;
@Override
public boolean hasNext() {
return pos < size;
}
@Override
public Object next() {
return elementData[pos++];
}
}
}
客户端
public class Client {
static ICollection list = new IArrayList();
static{
for(int i = 0;i<10;i++){
list.add(i);
}
}
public static void main(String[] args) {
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
四.使用场景
- 当需要为遍历不同的容器结构提供一个统一的接口
- 当访问一个容器对象的内容而无需暴露其内部细节的表示
- 后期大概率扩展新的容器类和迭代器类,无需修改原有代码
五.在JDK中的应用
日常开发过程中,我们大量的使用iterator迭代器去遍历Java提供的各种集合,对于如何使用迭代器并不陌生。这里以ArrayList为例,来看看是如何实现的
java.util.ArrayList中是使用一个内部类Itr完成对ArrayList中数据的遍历,我们看到这可能会产生两个疑问
- 1.为什么不让ArrayList类去实现Iterator接口?
为了满足单一职责原则,将遍历数据的职责拆分给了内部的迭代器类 - 2.为什么要采用内部类的方式?
封装的思想,防止外部滥用,同时将遍历的细节隐藏起来,调用者无需关心容器内有多少数据以及如何去遍历数据
最后来看看UML类图,发现Java提供的集合与迭代器之间还使用了工厂方法模式,由每一个具体的集合去生产具体的迭代器