定义
迭代器模式(Iterator Pattern)主要是提供了一种访问一个容器对象中各个元素的方法,并且不会暴露该对象的内部细节。迭代器模式是一种对象行为型模式。
在Java的集合的处理中就经常会使用到迭代器,集合是一个可以包容对象的容器,比如List,Set,Map,可以使用迭代器把容器中的对象一个一个地遍历获取。比如:
public class IteratorTest { public static void main(String[] args) { // 创建集合 ArrayList<String> sites = new ArrayList<String>(); sites.add("张飞"); sites.add("刘备"); sites.add("关羽"); sites.add("赵云"); // 获取迭代器 Iterator<String> it = sites.iterator(); // 输出集合中的第一个元素 System.out.println(it.next()); } } 复制代码
结果如下:
组成部分
要想实现一个迭代器模式主要有以下四个部分:
1、抽象容器(Aggregate):定义存储、添加、删除聚合对象以及创建迭代器对象的接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
2、具体容器类(Concrete Aggregate):实现抽象容器类,返回一个具体迭代器的实例,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
3、抽象迭代器(Iterator):抽象迭代器是定义访问和遍历聚合元素的接口,通常包含三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),以及判断是否有下一个元素的hasNext()方法。
4、具体迭代器实现类(Concretelterator):实现抽象迭代器接口中所定义的方法,完成集合的迭代,并且记录遍历的当前位置。
例子
接下来实现一个迭代器模式的具体的例子:
首先定义一个抽象容器的接口:
/** * 抽象容器的接口 */ public interface Aggregate { public void add(Object obj); public void remove(Object obj); public Iterator iterator(); } 复制代码
再定义一个具体的容器类实现抽象容器接口并且实现接口方法:
public class ConcreteAggregate implements Aggregate{ private List list = new ArrayList(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator(list); } } 复制代码
迭代器接口:
public interface Iterator { public Object next(); public boolean hasNext(); } 复制代码
具体的迭代器类实现迭代器接口:
public class ConcreteIterator implements Iterator { public List list = new ArrayList(); public int index = 0; public ConcreteIterator(List list) { this.list = list; } @Override public Object next() { Object obj = null; if(this.hasNext()){ obj = this.list.get(index++); } return obj; } @Override public boolean hasNext() { if(index==list.size()){ return false; } return true; } } 复制代码
测试类:
public class IteratorPatternTest { public static void main(String[] args) { Aggregate aggregate = new ConcreteAggregate(); aggregate.add("刘备"); aggregate.add("关羽"); aggregate.add("张飞"); Iterator it = aggregate.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); } } } 复制代码
运行结果:
迭代器模式的优点
1、访问一个集合的内容而无须暴露它的内部表示,并且遍历任务交由迭代器完成,这简化了集合类;
2、封装性良好,为遍历不同的聚合结构提供一个统一的接口,并且用户只需要得到迭代器就可以遍历,而不需要关心遍历的算法;
迭代器模式的缺点
1、如果需要便利简单的集合,比如数组或者list,使用迭代器方式就比较麻烦,所以采用迭代器需要选择合适的场景;
2、迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常;
应用场景
迭代器模式适用于以下几种情况:
1、如果需要访问一个集合对象的内容,但是又不需要暴露它的内部细节,那么可以使用迭代器模式;
2、如果需要遍历不同的集合结构并为其提供一个统一的接口,也可以使用迭代器模式;
3、迭代器和容器的关系比较密切,并且很多语言在实现容器的时候都提供了迭代器,所以可以一般采用语言提供的迭代器模式就可以了,不需要可以的去实践迭代器模式。
总结
迭代器模式主要是提供了一种访问一个容器对象中各个元素的方法,并且不会暴露该对象的内部细节。但是很多语言在实现容器的时候都提供了迭代器,所以可以一般采用语言提供的迭代器模式就可以了,不需要刻意的去实践迭代器模式。
最后本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star。