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