1. 什么是迭代器模式?
《Head First设计模式》定义,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
迭代器模式让我们能游走于聚合对象内的每一个元素,而又不暴露其内部的表示。
当多线程引用同一个集合的迭代器时,可能会出现意想不到的错误,所以多线程使用迭代器时,必须特别小心。
迭代器模式属于行为型模式
对于迭代器来说,数据结构可以是有序的也可以是无序的,甚至数据可以是重复的。除非集合有特别说明,否则不可以对迭代器所取出的元素大小顺序作出假设。
2. 角色
迭代器抽象接口(Iterater):这是所有迭代器必须要实现的接口。它包含了一些方法,利用这些方法可以在集合元素之间游走。可以使用java.util.Iterator。如果不想使用java的迭代器,也可以自己设计一个迭代器接口。
具体迭代器(ConcreteIterator):具体迭代器负责管理目前遍历的位置。
抽象聚合接口(Aggregate):有一个共同的接口供所有的聚合(容器)使用,将客户代码从集合对象的实现中解耦了。
具体聚合类(ConcreteAggregate):具体聚合(容器)类持有一个对象的集合,并实现一个方法,利用此方法返回集合的迭代器。
图片来源于《Head First设计模式》
3. 优点
(1)支持以不同的方式遍历一个聚合对象。
(2)迭代器简化了聚合类。
(3)在同一个聚合上可以有多个遍历。
(4)在迭代器模式中,增加新的迭代器类和聚合类都很方便,无需修改原有代码。
4. 缺点
迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要增加对应的迭代器类,类个数成对增加,一定程度上增加了系统的复杂性和运行开销。
5. 使用场景
(1)访问一个聚合对象的内容,但又不想知道聚合对象的内部实现细节。
(2)想为聚合对象提供多种遍历方式。
(3)为遍历不同聚合对象提供一个统一的接口。
6. 示例代码
(1)抽象迭代器类
/**
* 迭代器抽象类
*/
public interface Iterator {
public boolean hasNext();
public Object next();
}
(2)具体迭代器类
/**
* 具体迭代器类
*/
public class ConcreteIterator implements Iterator {
//存数据的集合
private List<Object> list=new ArrayList<Object>();
//游标
private int cursor=0;
public ConcreteIterator(List<Object> list) {
this.list=list;
}
@Override
public boolean hasNext() {
if(cursor==list.size())
return false;
return true;
}
@Override
public Object next() {
Object obj=null;
if(hasNext()){
//注意此处cursor++和++cursor的区别
obj= list.get(cursor++);
}
return obj;
}
}
(3)抽象聚合类
/**
* 抽象聚合接口
*/
public interface Aggregate {
public void add(Object object);
public void remove(Object object);
public Iterator iterator();
}
(4)具体聚合类
/**
* 具体聚合类
*/
public class ConcreteAggregate implements Aggregate {
private List<Object> list=new ArrayList<Object>();
@Override
public void add(Object object) {
list.add(object);
}
@Override
public void remove(Object object) {
list.remove(object);
}
@Override
public Iterator iterator() {
return new ConcreteIterator(list);
}
}
(5)测试代码
public static void main(String[] args) {
//创建集合对象
ConcreteAggregate ca=new ConcreteAggregate();
//添加数据
ca.add("A");
ca.add("B");
ca.add("C");
ca.add("D");
ca.add("E");
ca.add("F");
ca.add("G");
//删除数据
ca.remove("A");
//获取迭代器遍历数据
Iterator iterator=ca.iterator();
while (iterator.hasNext()) {
Object obj = (Object) iterator.next();
System.out.print(obj);
}
}
(6)测试结果
BCDEFG
【四川乐山程序员联盟,欢迎大家加群相互交流学习5 7 1 8 1 4 7 4 3】