迭代器模式-Iterator(Java实现)

迭代器模式-Iterator

用于访问一个集合中的各个元素, 而又不会暴露集合的内部的细节.

本文展示的例子就是, 在猫群组里, 用迭代器遍历每一只猫.

本文章的例子的继承关系图如下:

其中:

Cat就是猫的定义.

Aggregate是"群组" "集合" 的统一抽象定义.

CatGroup是猫群组.

Iterator是迭代器的接口.

CatGroupIterator是猫群组的迭代器. 用来遍历CatGroup里的每一个Cat.

 

如果把依赖关系加上的话, 如下:

迭代器接口

统一定义了迭代器该有的方法.

hasNext() 用于判断是否还有下一个元素

next() 用于返回下一个元素, 并且使内部计数器+1

/**
 * 迭代器接口
 */
public interface Iterator {
    public abstract boolean hasNext();

    public abstract Object  next();
}

用于生成迭代器的接口

/**
 * 该接口中只有一个方法, 这个方法用于生成一个迭代器, 并返回
 * <p>
 * 如果某个集合想使用迭代器, 那么就就应该实现这个接口
 */
public interface Aggregate {
    public abstract Iterator iterator();
}

元素类

本例子中举的是"猫群组"中利用迭代器来遍历每一只猫

所以在创建猫群组之前, 先把"猫类" 定义好

/**
 * Cat是个体, 一个Cat实例代表一只猫.
 * CatGroup是Cat的集合, 一个CatGroup实例代表一群猫.
 */
public class Cat {
    private int    age;
    private String name;

    public Cat(String name, int age) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

集合类

接下来创建"猫群组"类

猫群组类想要使用迭代器的话, 需要先实现Aggregate接口的iterator()方法, 来获提供群组的迭代器.

/**
 * Cat是个体, 一个Cat实例代表一只猫.
 * CatGroup是Cat的集合, 一个CatGroup实例代表一群猫.
 *
 * 并且这个类实现了Aggregate的iterator()方法来获取迭代器
 */
public class CatGroup implements Aggregate {

    private int last;
    private Cat[] cats;

    public CatGroup(int maxsize) {
        this.cats = new Cat[maxsize];
    }

    public Cat getByIndex(int index) {
        return cats[index];
    }

    public void append(Cat cat) {
        cats[last++] = cat;
    }

    public int getLength() {
        return last;
    }

    @Override
    public Iterator iterator() {
        return new CatGroupIterator(this);
    }
}

集合迭代器类

接下来介绍猫群组的迭代器.

hasNext() 用于判断猫群组里是否还有下一只猫. 如果 index 小于 猫群组中猫的个数, 那么肯定有下一只; 否则, 肯定没有下一只猫, 表示已经遍历完所有猫了

next()方法负责直接返回"下一只猫" 并且把计数器+1.

public class CatGroupIterator implements Iterator {
    private int index;
    private CatGroup catGroup;

    public CatGroupIterator(CatGroup catGroup) {
        this.catGroup = catGroup;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        return index < catGroup.getLength();
    }

    @Override
    public Object next() {
        return catGroup.getByIndex(index++);
    }
}

测试

public class Main {
    public static void main(String[] args) {
        // 创建一个猫群
        CatGroup catGroup = new CatGroup(20);

        // 向猫群里添加猫
        catGroup.append(new Cat("betty", 10));
        catGroup.append(new Cat("nancy", 11));
        catGroup.append(new Cat("wood", 14));
        catGroup.append(new Cat("zira", 18));

        // 获取遍历该猫群的迭代器
        Iterator iterator = catGroup.iterator();

        // 迭代并输出
        while (iterator.hasNext()) {
            Cat c = (Cat) iterator.next();
            System.out.println(c);
        }
    }
}

这段代码的github地址: https://github.com/GoldArowana/design-patterns/tree/master/src/main/java/com/king/patterns/iterator

总结

为什么使用迭代器, 而不是使用数组+下角标的方法来遍历数组呢?

因为这样就可以把遍历一个集合的api进行统一. 无论是数组还是链表或者是其他集合, 都可以用迭代器来进行统一调用.

也就是说Iterator把一个集合的实现和遍历进行了分离.

posted @ 2018-05-06 23:43  GoldArowana  阅读(1087)  评论(0编辑  收藏  举报