迭代器模式

沙海 2021年6月22日05:39:53Java评论43字数 4788阅读15分57秒阅读模式
摘要

智能摘要

智能摘要文章源自JAVA秀-https://www.javaxiu.com/34612.html

Iterator大家应该都很熟悉了,作为Java程序员的我们来说,遍历集合这也是我们刚开始学习Java知识。这次要跟大家分享的设计模式就是这迭代器模式,虽然很多语言都直接把Iterator封装到基础工具类中,但是它的特性你都了解吗?导致了数组会发生ao bing没有遍历到,因为数据迁移而丢失了。同样的假设在后面添加元素按照向后迁移,还能遍历到,那如过插入的数据是在已经遍历的之前呢?迭代器模式封装集合内部的复杂数据结构,不用关心需要遍历的对象。文章源自JAVA秀-https://www.javaxiu.com/34612.html

原文约 2378 | 图片 5 | 建议阅读 5 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器模式

原创 三太子敖丙 三太子敖丙 文章源自JAVA秀-https://www.javaxiu.com/34612.html

收录于话题文章源自JAVA秀-https://www.javaxiu.com/34612.html

#设计模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

10个文章源自JAVA秀-https://www.javaxiu.com/34612.html

Iterator大家应该都很熟悉了,作为Java程序员的我们来说,遍历集合这也是我们刚开始学习Java知识。文章源自JAVA秀-https://www.javaxiu.com/34612.html

遍历集合的方式也有很多,比如for循环、while循环、foreach循环、Iterator等。这里的Iterator就是我们设计模式里面的迭代器模式。文章源自JAVA秀-https://www.javaxiu.com/34612.html

这次要跟大家分享的设计模式就是这迭代器模式,虽然很多语言都直接把Iterator封装到基础工具类中,但是它的特性你都了解吗?文章源自JAVA秀-https://www.javaxiu.com/34612.html

设计模式系列往期文章:文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 单例模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 工厂模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 流程引擎文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 建造者模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 原型模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 责任链模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 观察者模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 策略模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

本期大纲

迭代器模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

定义

迭代器大家都很熟悉,那么什么叫迭代器?它的目的又是什么呢?文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 定义:我们可以用相同的方式处理集合,无论它是列表还是数组,它都提供了一种迭代其元素而不用暴露其内部结构的机制,更重要的是,不同的类型的集合都可以使用相同的统一机制,这种机制则被称为 迭代器模式。文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 目的:提供一种顺序遍历聚合对象元素,而不暴露其内部实现的方法。文章源自JAVA秀-https://www.javaxiu.com/34612.html

    以上定义来之设计模式之美文章源自JAVA秀-https://www.javaxiu.com/34612.html

解析图:文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • Aggregate(抽象容器):负责提供创建具体迭代器角色的接口,对应于java.util.Collection接口。文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • Iterator(抽象迭代器):迭代器的抽象类,它定义遍历容器对象的操作以及返回对象的操作文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • ConcreteAggregate(具体容器):主要是可以实现内部不同的结构。但会暴露处理遍历容器的具体迭代器。文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • ConcreteIterator(具体迭代器):处理特定的具体容器类的具体迭代器,实际上对于每个容器具体容器,都必须实现一个具体的迭代器。文章源自JAVA秀-https://www.javaxiu.com/34612.html

整个图看起来其实就两个东西,一个容器,一个迭代器。文章源自JAVA秀-https://www.javaxiu.com/34612.html

代码实现

这次就不举列了。直接手写一个迭代器,我们再测试一下。文章源自JAVA秀-https://www.javaxiu.com/34612.html

主要还是理解迭代器到底是干嘛用的:文章源自JAVA秀-https://www.javaxiu.com/34612.html

能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素文章源自JAVA秀-https://www.javaxiu.com/34612.html

话不多说,还是直接上手撸代码文章源自JAVA秀-https://www.javaxiu.com/34612.html

public interface Aggregate {    // 添加元素    void add(Object object);    // 移除元素    void remove(Object object);    // 迭代器    Iterator iterator();}

按照上面的类图,先是创建抽象容器,定义几个基本添加删除元素方法,以及迭代器文章源自JAVA秀-https://www.javaxiu.com/34612.html

public interface Iterator<E> {    // 判断容器是否有值    boolean hasNext();    // 把游标执向下一个指针    void next();    // 当前遍历的数据    E currentItem();}

其次 再试创建抽象迭代器,遍历容器中的数据文章源自JAVA秀-https://www.javaxiu.com/34612.html

public class ConcreteAggregate implements Aggregate {    private ArrayList arrayList = new ArrayList();    @Override    public void add(Object object) {        this.arrayList.add(object);    }    @Override    public void remove(Object object) {        this.arrayList.remove(object);    }    @Override    public Iterator iterator() {        return new ConcreteIterator(this.arrayList);    }}

开始定义我们具体的容器了,内部定一个ArrayList容器,用来存放数据,当然这里大家也可以改成其他的容器 比如说用Vector 或者其他的 栈、 树、 图 等文章源自JAVA秀-https://www.javaxiu.com/34612.html

public class ConcreteIterator<E> implements Iterator<E> {    private int cursor; // 游标    private ArrayList arrayList;    public ConcreteIterator(ArrayList arrayList) {        this.cursor = 0;        this.arrayList = arrayList;    }    @Override    public boolean hasNext() {        if (this.cursor == this.arrayList.size()) {            return false;        }        return true;    }    @Override    public void next() {        cursor++;        System.out.println(cursor + "   cursor");    }    @Override    public E currentItem() {        if (cursor >= arrayList.size()) {            throw new NoSuchElementException();        }        E e = (E) arrayList.get(cursor);        this.next();        return e;    }     // 测试demo    public static void main(String[] args) {        Aggregate aggregate = new ConcreteAggregate();        aggregate.add("java");        aggregate.add("c++");        aggregate.add("php");        aggregate.add("敖丙");        Iterator iterator = aggregate.iterator();        while (iterator.hasNext()) {            System.out.println(iterator.currentItem());        }      // 结果:1    java      //      2     c++      //      3     php      //      4     敖丙    }}

最后就是实现具体的迭代器了, 在currentItem里面根据遍历的游标,获取数组里面的值文章源自JAVA秀-https://www.javaxiu.com/34612.html

同时在main方法里面就是测试demo了,以上就是简单的手撸迭代器了。文章源自JAVA秀-https://www.javaxiu.com/34612.html

这里面我们其实还可以有其它的各种特别的玩法,比如说怎么实现暂停遍历等,只有了解内部实现,我们才能改造出符合当前所需要的业务代码。文章源自JAVA秀-https://www.javaxiu.com/34612.html

Java中的迭代器

在Java的中也有迭代器,java.util.Iterator类以及java.util.Collection,就是典型的迭代器喝容器的列子,接下来看看具体的源码文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

当next没有值的时候则会抛出NoSuchElementException异常信息,上面的手撸异常也是根据这个来的文章源自JAVA秀-https://www.javaxiu.com/34612.html

在Java中 常见的 List、Set、Queue都是extend Collection(容器),而Collection又定义迭代器Iterator,这就是能直接使用的原因了。文章源自JAVA秀-https://www.javaxiu.com/34612.html

Java集合分析

上面我们看完了Java中的迭代器,不知道,大家注意了没有,我们在使用迭代器的时候是不能再对集合进行增减操作的,否则就会抛出ConcurrentModificationException异常文章源自JAVA秀-https://www.javaxiu.com/34612.html

那么问题来了,为什么会有这个异常信息呢?文章源自JAVA秀-https://www.javaxiu.com/34612.html

看过ArrayList源码的同学都知道底层是数据结构中的数组结构的,所以我们看下接下来图结构文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器模式文章源自JAVA秀-https://www.javaxiu.com/34612.html

假设现在开始在遍历当前这个数组,当从第一步执行到第二步,都是正常运行的,假设现在执行完第二步,开始走第三步时文章源自JAVA秀-https://www.javaxiu.com/34612.html

删除 java这个元素,数组为了保持存储数据的连续性,当删除java数据时,是会发生数组元素的迁移的。所以正常步骤3应该是遍历到aobing元素的变成当前数组元素已经是ao bing了。文章源自JAVA秀-https://www.javaxiu.com/34612.html

导致了数组会发生ao bing没有遍历到,因为数据迁移而丢失了。文章源自JAVA秀-https://www.javaxiu.com/34612.html

同样的假设在后面添加元素按照向后迁移,还能遍历到,那如过插入的数据是在已经遍历的之前呢?文章源自JAVA秀-https://www.javaxiu.com/34612.html

这样整个遍历就变成不可预估了。文章源自JAVA秀-https://www.javaxiu.com/34612.html

  public static void main(String[] args) {        List<String> aggregate = new ArrayList();        aggregate.add("java");        aggregate.add("c++");        aggregate.add("php");        aggregate.add("敖丙");        Iterator<String> iterator = aggregate.iterator();        while (iterator.hasNext()) {            iterator.remove(); // 添加这行代码 java.lang.IllegalStateException            System.out.println(iterator.next());            iterator.remove(); // 正常        }    }

再来看这个测试demo,同样都是调用remove方法,不同的地方结果不一样,这也就是刚好印证上面的图体现的问题,所以要解决这个问题,要么就是遍历的时候不允许增删元素,要么是增删元素之后让遍历报错。文章源自JAVA秀-https://www.javaxiu.com/34612.html

通过上面的列子已经了解了迭代器的原理以及实现,大家可以根据自己所需要的场景改造迭代器,很多公司的一些自己的框架或者工具类等等都是通过现有框架源码进行改造而来。文章源自JAVA秀-https://www.javaxiu.com/34612.html

迭代器的优点:文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 迭代器模式封装集合内部的复杂数据结构,不用关心需要遍历的对象。文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 符合单一职责原则以及开闭原则文章源自JAVA秀-https://www.javaxiu.com/34612.html

  • 可以对遍历进行把控暂停或者继续文章源自JAVA秀-https://www.javaxiu.com/34612.html

总结

迭代器设计模式在我们业务场景中自己写的代码中 我个人是觉得比较少见的,至少到目前我还没有怎么发现有好的业务场景可以用这个模式,所以这里我就不给大家举例业务代码改造了。(毕竟不能因为设计模式而强行设计)文章源自JAVA秀-https://www.javaxiu.com/34612.html

跟大家分享迭代器主要是想让大家了解Java集合遍历怎么实现的,方便我们提升自己以后的看源码的能力,以及提升自己的设计能力。文章源自JAVA秀-https://www.javaxiu.com/34612.html

后面就再跟大家再聊聊动态代理设计模式,就不会再详细讲了其他的模式了,因为本身不怎么常见,作为了解还是会和大家做一个总结分享。文章源自JAVA秀-https://www.javaxiu.com/34612.html

今天的迭代器模式到此结束,我是敖丙,你知道的越多,你不知道的越多,我们下期见!!!文章源自JAVA秀-https://www.javaxiu.com/34612.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
  • 版权声明:本站是JAVA秀团队的技术分享社区,我们会经常分享资源和教程。
  • 转载请注明:迭代器模式 - JAVA秀 ☜(ˆ▽ˆ)
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定