一、概述
提供一种方法来访问聚合对象(容器container),而不用暴露这个对象的内部细节。
二、适用场景
1>遍历访问聚合对象中的元素,而无须暴露它的内容表示,将聚合对象的访问和内部数据的存储分离。使得访问聚合对象时无须了解其内部的实现细节。
2>需要为一个聚合对象提供多种遍历实现。
三、UML类图
四、参与者
1>Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法,例如:用于获取第一个元素的first()方法,用于访问下一个元素的next()方法,用于判断是否还有下一个元素的hasNext()方法,用于获取当前元素的currentItem()方法等,在具体迭代器中将实现这些方法。
2>ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。
3>Aggregate(抽象聚合类):它用于存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。
4>ConcreteAggregate(具体聚合类):它实现了在抽象聚合类中声明的createIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。
五、用例学习
1、抽象迭代器 Iterator.java
/**
* 自定义迭代器接口<br/>
* <b>说明:</b>
* 此处没有使用JDK内置的迭代器接口 java.util.Iterator<E>
* @author lvzb.software@qq.com
*
*/
public interface Iterator {
/** 将游标指向第一个元素 */
public Object first();
/** 将游标指向下一个元素 */
public Object next();
/** 判断是否存在下一个元素 */
public boolean hasNext();
/** 返回游标指向的当前元素 */
public Object currentItem();
}
2、具体迭代器 ConcreteIterator.java
/**
* 具体迭代器实现类<br/>
* 访问聚合对象、对聚合对象内部元素遍历
* @author lvzb.software@qq.com
*
*/
public class ConcreteIterator implements Iterator {
// 维持一个对具体聚合对象的引用,以便于访问存储在聚合对象中的数据
private Aggregate aggregate;
// 定义一个游标,用于记录当前访问位置
private int cursorIndex;
public ConcreteIterator(Aggregate aggregate){
this.aggregate = aggregate;
}
@Override
public Object first() {
cursorIndex = 0;
return aggregate.getObjects().get(cursorIndex);
}
@Override
public Object next() {
cursorIndex++ ;
if(hasNext()){
return aggregate.getObjects().get(cursorIndex);
}
return aggregate.getObjects().get(0);
}
@Override
public boolean hasNext() {
if (cursorIndex < aggregate.getObjects().size()) {
return true;
}
return false;
}
@Override
public Object currentItem() {
return aggregate.getObjects().get(cursorIndex);
}
}3、抽象聚合类 Aggregate.java
import java.util.ArrayList;
import java.util.List;
/**
* 抽象聚合对象
* @author lvzb.software@qq.com
*
*/
public abstract class Aggregate {
/** 创建迭代器 具体创建什么样迭代方式的迭代器由具体的子类去实现 */
public abstract Iterator createIterator();
protected List<Object> objects = new ArrayList<Object>();
public Aggregate(List objects) {
this.objects = objects;
}
public void addObject(Object obj){
objects.add(obj);
}
public void deleteObject(Object obj){
objects.remove(obj);
}
public List<Object> getObjects(){
return objects;
}
}4、具体聚合类 ConcreteAggregate.java
import java.util.List;
/**
* 具体聚合对象
* @author lvzb.software@qq.com
*
*/
public class ConcreteAggregate extends Aggregate {
public ConcreteAggregate(List objects) {
super(objects);
}
/**
* 提供工厂方法 创建具体的迭代器实例<br/>
* 由迭代器去执行具体的聚合对象的遍历访问<br/>
* 这样就将聚合对象的数据存储 和 对聚合对象元素的访问进行了分离
*/
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
}5、客户端测试类 Client.java
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args){
List<String> nameList = new ArrayList<String>();
nameList.add("Java");
nameList.add("C");
nameList.add("C++");
// 实例化具体聚合对象 且 创建初始化集合数据
ConcreteAggregate languageAggregate = new ConcreteAggregate(nameList);
// 获取聚合对象关联的迭代器
Iterator iterator = languageAggregate.createIterator();
// 通过迭代器访问聚合对象的内部数据
String firstLanguage = (String) iterator.first(); // 访问聚合对象集合中索引为1的元素
System.out.println(firstLanguage);
boolean hasNext = iterator.hasNext();
System.out.println("是否还有下一个元素:" + hasNext);
if(hasNext){
String nextLanguage = (String) iterator.next();
System.out.println("下一个元素:" + nextLanguage);
}
}
}6、运行效果
Java 是否还有下一个元素:true 下一个元素:C
Java JDK内置的迭代器:
说到迭代器模式 给我们的第一联想就是Java中 我们使用最最频繁的java.util.Iterator接口啦。
没错 他就是JDK中内置的迭代器。public interfaceIterator<E> 对collection进行迭代的迭代器。
这里想扩展的一个点是:关于接口Iterator的子接口ListIterator<E>的介绍
这个ListIterator子接口 也许我们平时的代码中使用的少,那么他有什么功能呢?
下面先看两张截图<比较比较 答案就在其中>
Iterator API方法:
ListIterator API方法:
从上面两个截图分析中我们可以看出Iterator只能进行单向遍历,而ListIterator可以进行双向遍历(向前/向后),且可以在迭代期间修改列表。最后附上一张截图如下:
JAVA设计模式之 迭代器模式【Iterator Pattern】
原文地址:http://blog.csdn.net/janice0529/article/details/41633027