迭代器模式——以统一的方式访问聚合对象中的元素

  我们都知道,在计算机中,内存本质上是可以理解为一种类似抽屉的东西,在内存中放置一组集合对象,就有两种的方式:一种是连续放置,在java和c等编程语言中就是数组,这种放置方式放置和获取元素都比较方便,直接用下表就可以,但是扩容比较麻烦;另一种就是随便放,在每一个元素中记录下一个的内存地址,在java中就是链表的方式,这种方式天然支持良好的扩展性,但是随机访问就比较麻烦。而且在链表的基础上,为了取存更加的方便,后面还设计出了二叉树等各种数据结构,在不同的数据结构上,访问集合中的各种元素其实是依赖于数据结构本身的,使用起来就比较麻烦。为了向普通使用者屏蔽这种具体的结构,迭代器模式就应用而生了。迭代器提供了一种统一访问内部元素的方式,每种集合只要实现迭代器的接口,客户端就可以统一的访问内部元素,而不需要感知里面的具体实现。
  在java语言中,已经内置实现了迭代器,而且我们能用到的集合基本上实现了迭代器的功能,所以我们平时只是用轮子,并不需要我们再去造轮子。为了学习迭代器模式,我们这里可以简单实现一个迭代器的功能,供大家参考学习。

自己实现一个迭代器

  实现迭代器其实有两个维度:一个是迭代器本身的接口,提供了统一访问其中的元素的方法;另一个维度是集合的维度,要在集合中根据集合本身的元素,创建一个迭代器,然后客户端才能使用迭代器。具体代码如下:

1. 创建一个迭代器的接口,并写一个具体的实现类

/**
 * 迭代器模式接口
 */
public interface Iterator<E> {
    /**
     * 判断是否含有下一个元素
     *
     * @return :
     */
    boolean hasNext();

    /**
     * 获取下一个元素
     *
     * @return :
     */
    E next();

}
/**
 * 迭代器的具体实现类
 */
public class ConcreteIterator<E> implements Iterator<E> {
    /**
     * 持有一个对象的集合
     */
    private final List<E> list;

    /**
     * 保存当前的index
     */
    private int index = 0;

    public ConcreteIterator(Collection<E> collection) {
        list = new ArrayList<>(collection == null ? 0 : collection.size());
        if (collection != null || collection.size() > 0) {
            list.addAll(collection);
        }
    }

    @Override
    public boolean hasNext() {
        return index < list.size();
    }

    @Override
    public E next() {
        return list.get(index++);
    }
}

2. 创建一个集合的接口,并写一个具体的集合实现类,在实现类中,我们就内部直接用java的list来模拟内部的存储

/**
 * 集合的接口
 */
public interface Aggregate<E> {

    /**
     * 添加
     *
     * @param e :
     * @return :
     */
    boolean add(E e);

    /**
     * 删除
     *
     * @param e :
     * @return :
     */
    boolean remove(E e);

    /**
     * 创建迭代器
     *
     * @return :
     */
    Iterator<E> createIterator();
}
/**
 * 集合的具体实现
 *
 * @param <E>
 */
public class ConcreteAggregate<E> implements Aggregate<E> {
    private final List<E> list = new ArrayList<>();

    @Override
    public boolean add(E e) {
        return list.add(e);
    }

    @Override
    public boolean remove(E e) {
        return list.remove(e);
    }

    @Override
    public Iterator<E> createIterator() {
        return new ConcreteIterator<>(this.list);
    }
}

3. 编写一个测试类

public class Client {

    @Test
    public void testIterator() {
        //创建并初始化集合
        Aggregate<String> aggregate = new ConcreteAggregate<>();
        aggregate.add("111");
        aggregate.add("222");
        aggregate.add("333");
        aggregate.add("444");
        aggregate.add("555");
        aggregate.add("666");
        aggregate.add("777");
        //用迭代器方式访问
        Iterator<String> iterator = aggregate.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

测试结果如下:

111
222
333
444
555
666
777

4. 类图如下

迭代器模式类图

迭代器模式的思考

  • java等高级语言中已经基本上都实现了迭代器的功能,我们并不需要重新造轮子,只需要知道怎么用和理解迭代器的思想即可
  • 在实际的开发中,我们有很多地方还是能够用到迭代器的思路的,比如需要分页获取一大堆数据的时候,我们就可以利用迭代器的思想,在获取的对象中实现hasNext()和next()方法,统一的迭代获取数据,将具体的实现封装在获取的对象中。
  • 设计模式是一种思维方式,平时看着用不上的东西,并不代表我们不需要学,往往在后续的功能开发中,就会用到其思想,给我们提供一种新的思路。

后记
  个人总结,欢迎转载、评论、批评指正

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值