Java大话设计模式学习总结(二十)---迭代器模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a770794164/article/details/90712051

迭代器模式(Iterator),提供一种方放顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。当你需要对聚集有多种方式遍历时,也可以考虑使用迭代器模式。

来自大话设计模式
简单来说,迭代器一般都是和集合同时出现的,只要定义了一个集合,一般都需要提供一个迭代器用来遍历集合内的元素。先举例一个自定义的集合和他的迭代器:

  1. 定义抽象迭代器类,一般都需要得到开始对象、下一个对象、是否遍历完、获取当前遍历到的集合内的元素
abstract class Iterator {
    public abstract Object first();
    public abstract Object next();
    public abstract boolean isDone();
    public abstract Object currentItem();
}
  1. 抽象集合类,拥有一个创建迭代器的抽象方法,添加元素,获取集合的元素个数,以及获取集合中某个元素的方法
abstract class Collection {
    public abstract Iterator createIterator();
    public abstract void add(Object object);
    public abstract int size();
    public abstract Object get(int index);
}
  1. 抽象集合类的实现类
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);
    }
}
  1. 抽象迭代器的实现类
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;
    }

}
  1. 主程序
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对大部分集合进行了封装并实现了迭代器,所以迭代器模式可能不太常用。

猜你喜欢

转载自blog.csdn.net/a770794164/article/details/90712051