Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。提供一种方法顺序的访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
一般情况,我们自己开发时很少自定义迭代器,因为java本身已经把迭代器做到内部中了(比如:常用的list和set中都内置了迭代器)。当然,如果真有这种需求需要我们自定义迭代器的话,可以参考jdk的迭代器实现方式来实现自己的迭代器。
解决问题:
不同的方式来遍历整个聚合对象。用于遍历一个聚合对象。
解决方式:把在元素之间游走的责任交给迭代器,而不是聚合对象。
迭代器模式的UML图:
责任和职责:
Iterator(迭代器接口):
该接口必须定义实现迭代功能的最小定义方法集
比如提供hasNext()和next()方法。
ConcreteIterator(迭代器实现类):
迭代器接口Iterator的实现类。可以根据具体情况加以实现。
Aggregate(容器接口):
定义基本功能以及提供类似Iteratoriterator()的方法。
ConcreteAggregate(容器实现类):
容器接口的实现类。必须实现Iteratoriterator()方法。
通用代码实现:
/**
* 迭代器接口
* @author arain.liu
*
*/
public interface Iterator<T> {
/**
* 是否还有下一个元素
* @return
*/
boolean hasNext();
/**
* 返回当前位置的元素,并将位置移动到下一位
* @return
*/
T next();
}
/**
* 具体迭代器
* @author arain.liu
*
*/
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> list = new ArrayList<>();
private int cursor = 0;
public boolean hasNext() {
return cursor != list.size();
}
public T next() {
T obj = null;
if (this.hasNext()) {
obj = this.list.get(cursor++);
}
return obj;
}
}
/**
* 容器接口
* @author arain.liu
*
*/
public interface Aggregate<T> {
/**
* 添加一个元素
* @param obj 元素对象
*/
void add(T obj);
/**
* 移除一个元素
* @param obj 元素对象
*/
void remove(T obj);
/**
* 获取容器的迭代器
* @return 迭代器对象
*/
Iterator<T> iterator();
}
/**
* 具体容器接口
* @author arain.liu
*/
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> list = new ArrayList<>();
@Override
public void add(T obj) {
list.add(obj);
}
@Override
public void remove(T obj) {
list.remove(obj);
}
@Override
public Iterator<T> iterator() {
return new ConcreteIterator<>();
}
}
/**
* Client类
* @author arain.liu
*/
public class MainClass {
public static void main(String[] args) {
Aggregate<String> agt = new ConcreteAggregate<>();
agt.add("aLin");
agt.add("jack");
agt.add("yushao");
Iterator<String> itr = agt.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}
迭代器优点:
1、实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。
2、隐藏容器的实现细节。
3、为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。
4、可以为容器或其子容器实现不同的迭代方法或多个迭代方法。
缺点:
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。