设计模式-迭代器模式

简述

1)在开发过程中我们都需要对许多数据进行操作,为了保存这些数据我们会把这些数据存放在容器中,待需要使用的时候再从容器中取出来使用。

2)为了我们使用的方便,我们会把容器定义成不同的数据结构,例如:队列、链表、栈,树等,就是为了让我们使用数据方便。

3)使用数据的时候我们就要对这些容器进行遍历,不同的数据结构有不同的遍历方法,甚至相同的数据结构会有多种遍历方法,例如树我们有前序遍历、中序遍历和后续遍历等

4)在编写这个容器的时候我们没有必要把这些遍历方法都写到容器中,这样就模糊了容器的主要功能,容器是用来存储数据的。

5)所以为了方便,我们就把遍历容器的方法抽取出来,形成了迭代器模式。

6)迭代器模式,提供一种遍历容器元素的同一接口,用一致的方法遍历容器元素,不需要知道容器的底层表示,即:不暴露内部结构

原理

在这里插入图片描述
1)Iterator:迭代器接口,是系统提供,含义 hasIlext,next,remove
2)ConcreteIterator :具体的容器类
3)Aggregate:一个统一的容器聚合接口,将客户端和具体迭代器解耦
4)Concretelggreage:具体的容器持有对象集合,并提供一个方法,返回一个送代器,该送代器可以正确遍历集合
5)Client:客户端,通过Iterator和Aggregate依赖子类

代码示例

底层是数组的容器

public class ArrayCollege implements College{
    /**
     * 容器
     */
    private Integer[] arr = new Integer[10];

    /**
     * 元素存放的位置
     */
    private int index = 0;

    public void add(Integer integer) {
        if (index >= arr.length ) {
            return;
        }
        arr[index++] = integer;
    }

    public void remove(Integer integer) {
        // 暂不实现
    }

    @Override
    public Iterator createIterator() {
        return new ArrayIterator(this.arr);
    }
}

底层是List的容器

public class ListCollege implements College{

    private List<Integer> list = new ArrayList<>();

    public void add(Integer integer) {
        list.add(integer);
    }

    public void remove(Integer integer) {
        // 暂不实现
    }

    @Override
    public Iterator createIterator() {
        return new ListIterator(this.list);
    }
}

写一个对数组的迭代器

public class ArrayIterator implements Iterator {

    /**
     * 容器 【迭代器是需要知道容器的底层数据结构的】
     *
     * 【 通过构造方法传进来】
     */
    private Integer[] arr;

    /**
     * 获取元素的指针
     */
    private int index = -1;

    public ArrayIterator(Integer[] arr) {
        this.arr = arr;
    }

    @Override
    public boolean hasNext() {
        if (++index >= arr.length) {
            return false;
        }
        if (arr[index] == null) {
            return false;
        }

        return true;
    }

    @Override
    public Object next() {

        return arr[index];
    }
}

写一个对List的迭代器

public class ListIterator implements Iterator {

    private List<Integer> list;

    private int index = -1;

    public ListIterator(List<Integer> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        if (++index >= list.size()) {
            return false;
        }

        return true;
    }

    @Override
    public Object next() {

        return list.get(index);
    }
}

写测试用例

public class Client {
    public static void main(String[] args) {
        ArrayCollege arrayCollege = new ArrayCollege();
        arrayCollege.add(1);
        arrayCollege.add(2);
        arrayCollege.add(3);

        Iterator iterator = arrayCollege.createIterator();

        while (iterator.hasNext()) {
            Integer next = (Integer) iterator.next();
            System.out.println(next);
        }

        System.out.println("=================================================");

        ListCollege listCollege = new ListCollege();
        listCollege.add(1);
        listCollege.add(2);
        listCollege.add(3);
        Iterator iterator1 = listCollege.createIterator();
        while (iterator1.hasNext()) {
            Integer next = (Integer) iterator1.next();
            System.out.println(next);
        }
    }
}

注意事项和细节

优点
1)提供一个统一的方法遍历对象,客户不用再考虑容器的类型,使用一种方法就可以遍历对象了。
2)隐藏了容器的内部结构,客户端要遍历容器的时候只能取到迭代器,而不会知道容器的具体组成。
3)提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任原则)。在容器类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,这样一来集合改变的话,只影响到容器对象。而如果遍历方式改变的话,只影响到了迭代器。
4)当要展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式

缺点
每个容器对象都要一个迭代器,会生成多个迭代器不好管理类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值