迭代器模式(Iterator),提供一种方放顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。当你需要对聚集有多种方式遍历时,也可以考虑使用迭代器模式。
简单来说,迭代器一般都是和集合同时出现的,只要定义了一个集合,一般都需要提供一个迭代器用来遍历集合内的元素。先举例一个自定义的集合和他的迭代器:
1.定义抽象迭代器类,一般都需要得到开始对象、下一个对象、是否遍历完、获取当前遍历到的集合内的元素
abstract class Iterator {
public abstract Object first();
public abstract Object next();
public abstract boolean isDone();
public abstract Object currentItem();
}
2.抽象集合类,拥有一个创建迭代器的抽象方法,添加元素,获取集合的元素个数,以及获取集合中某个元素的方法
abstract class Collection {
public abstract Iterator createIterator();
public abstract void add(Object object);
public abstract int size();
public abstract Object get(int index);
}
3.抽象集合类的实现类
import java.util.ArrayList;
class ConcreteCollection extends Collection {
private ArrayList<Object> items = new ArrayList<>();
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
@Override
public int size() {
return items.size();
}
@Override
public Object get(int index) {
return items.get(index);
}
@Override
public void add(Object object) {
items.add(object);
}
}
4.抽象迭代器的实现类
class ConcreteIterator extends Iterator {
private ConcreteCollection collection;
private int current = 0;
public ConcreteIterator(ConcreteCollection collection) {
this.collection = collection;
}
@Override
public Object first() {
return collection != null ? collection.get(0) : null;
}
@Override
public Object next() {
Object object = null;
if (collection != null) {
current++;
if (current < collection.size()) {
object = collection.get(current);
}
}
return object;
}
@Override
public boolean isDone() {
return collection != null ? current < collection.size() ? false : true : true;
}
@Override
public Object currentItem() {
return collection != null ? collection.get(current) : null;
}
}
5.主程序
//主代码程序
class Test1 {
public static void main(String[] args) {
Collection collection = new ConcreteCollection();
collection.add("no1");
collection.add("no2");
collection.add("no3");
collection.add("no4");
collection.add("no5");
Iterator iterator = collection.createIterator();
while (!iterator.isDone()) {
System.out.println(iterator.currentItem());
iterator.next();
}
}
}
运行结果如下:
现在要求从列表最后一位开始循环,这个时候新建一个迭代器的实现类,就能解决这个问题:
class ConcreteIteratorDesc extends Iterator {
private ConcreteCollection collection;
private int current = 0;
ConcreteIteratorDesc(ConcreteCollection collection) {
this.collection = collection;
this.current = collection.size() - 1;
}
@Override
public Object first() {
return collection.get(collection.size() - 1);
}
@Override
public Object next() {
Object object = null;
if (collection != null) {
current --;
if (current >= 0) {
object = collection.get(current);
}
}
return object;
}
@Override
public boolean isDone() {
return collection != null ? current < 0 ? true : false : true;
}
@Override
public Object currentItem() {
return collection != null ? collection.get(current) : null;
}
}
然后将ConcreteCollection类中,createIterator方法中的return new ConcreteIterator(this)调整为**return new ConcreteIteratorDesc(this)**即可。主程序不需要调整,运行结果为:
List集合本身也实现了迭代器相关的接口,以ArrayList为例,代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Iterator;
//主程序代码
class Test2 {
public static void main(String[] args) {
List<Object> collection = new ArrayList<>();
collection.add("no1");
collection.add("no2");
collection.add("no3");
collection.add("no4");
collection.add("no5");
Iterator<Object> iterator = collection.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println(object);
}
System.out.println("====== 准备倒叙 ======");
Collections.reverse(collection);
iterator = collection.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println(object);
}
}
}
运行结果如下:
总结:
迭代器模式让迭代器和集合对象进行了解耦。新增迭代方式可以不用修改集合对象,只需新增迭代器对象即可,符合了开放-封闭原则。个人感觉,因为java对大部分集合进行了封装并实现了迭代器,所以迭代器模式可能不太常用。