码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 设计模式之迭代器模式


    本文介绍设计模式中的迭代器模式,首先通俗的解释迭代器模式的基本概念和对应的四个角色,接着根据四个角色举一个典型的实例,为了加强知识的连贯性,我们以Jdk源码中迭代器模式的典型应用进一步说明,最后说明迭代器模式的应用场景和优缺点。

    读者可以拉取完整代码本地学习,实现代码均测试通过上传到 码云

    一、概念理解

    迭代器模式也就是提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。何为聚合对象呢?最典型的就是集合类。

    大白话也就是,集合中的数据是私有的,集合中不应该提供直接遍历的方法,要定义一个新的对象用于访问这个集合。

    在迭代器模式中有有四个角色:

    抽象聚合(InterfaceAggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。

    具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

    抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。

    具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

    基于四个角色我们举一个典型案例。

    二、案例实现

    抽象聚合角色:

    /**
     * 抽象聚合角色
     * @author tcy
     * @Date 13-09-2022
     */
    public interface InterfaceAggregate {
        /**
         * 增加对象
         * @param obj 对象
         */
        void add(Object obj);
    
        /**
         * 移除对象
         * @param obj 对象
         */
        void remove(Object obj);
    
        /**
         * 调用迭代器
         * @return 迭代器
         */
        Iterator getIterator();
    }
    

    具体聚合角色:

    /**
     * 具体聚合角色
     * @author tcy
     * @Date 13-09-2022
     */
    public class ConcreteAggregate implements InterfaceAggregate{
        private List list = new ArrayList<>();
        @Override
        public void add(Object obj) {
            list.add(obj);
        }
    
        @Override
        public void remove(Object obj) {
            list.remove(obj);
        }
    
        @Override
        public Iterator getIterator() {
            return new Concretelterator(list);
        }
    }
     
    

    抽象迭代器角色:

    /**
     * 抽象迭代器
     * @author tcy
     * @Date 13-09-2022
     */
    public interface Iterator {
    
        /**
         * 删除对象
         * @return 对象
         */
        Object remove();
    
        /**
         * 调用下一个对象
         * @return 对象
         */
        E next();
    
        /**
         * 迭代器中是否还有下一个对象
         * @return
         */
        boolean hasNext();
    
        /**
         * 遍历迭代器中剩余的对象
         * @param action
         */
        default void forEachRemaining(Consumer action) {
            Objects.requireNonNull(action);
            while (hasNext())
                action.accept(next());
        }
    
    }
    

    具体迭代器角色:

    /**
     * 具体迭代器角色
     * @author tcy
     * @Date 13-09-2022
     */
    public class Concretelterator implements Iterator{
        private List list = null;
        private int index = -1;
    
        public Concretelterator(List list) {
            this.list = list;
        }
    
        @Override
        public Object remove() {
            index = list.size();
            Object obj = list.get(index);
            list.remove(obj);
            return obj;
        }
    
        @Override
        public Object next() {
            Object obj = null;
            if (this.hasNext()) {
                obj = list.get(++index);
            }
            return obj;
        }
    
        @Override
        public boolean hasNext() {
            if (index < list.size() - 1) {
                return true;
            } else {
                return false;
            }
        }
    }
     
    

    客户端调用:

    /**
     * @author tcy
     * @Date 13-09-2022
     */
    public class Client {
    
        public static void main(String[] args) {
            ConcreteAggregate concreteAggregate=new ConcreteAggregate();
            concreteAggregate.add("老王");
            concreteAggregate.add("小王");
            concreteAggregate.add("小张");
    
            System.out.println("Aggregate聚合对象有:");
    
            Iterator iterator=concreteAggregate.getIterator();
    
            while (iterator.hasNext()){
                Object next = iterator.next();
                System.out.println(next.toString());
            }
            //遍历剩下的角色
            iterator.forEachRemaining(ele -> System.out.println(ele));
    
        }
    
    }
    

    三、源码应用

    迭代器模式在Jdk中的集合类中有广泛的应用。

    List抽象聚合类;

    ArrayList具体聚合角色;

    Iterator抽象迭代器;

    ArrayList内部类Itr是具体迭代器;

    我们可以看到ArrayList是把具体聚合角色和具体迭代器都写在一个类中,Itr是以内部类的形式。

    Iterator迭代器和我们举的样例长的都一样,都包含,hasNext()、next()、remove()、forEachRemaining()方法,我们重点说下forEachRemaining()方法,该方法代表的意思是遍历剩下的集合。

    比如我们已经调用了该集合中的第一个元素,那么遍历时候就会自动忽略第一个元素,遍历剩下的元素。

    我们写一个测试类看效果:

    public class Client {
    
        public static void main(String[] args) {
          
            // jdk ArrayList迭代器
            //创建一个元素类型为Integer的集合
            Collection collection =  new ArrayList<>();
    
                //向集合中添加元素
                collection.add("老王");
                collection.add("小王");
                collection.add("小张");
    
            //获取该集合的迭代器
            java.util.Iterator iteratorJdk= collection.iterator();
            System.out.println("Arraylist聚合对象有:");
            //调用迭代器的经过集合实现的抽象方法遍历集合元素
            while(iteratorJdk.hasNext())
            {
                System.out.println(iteratorJdk.next());
            }
            //调用forEachRemaining()方法遍历集合元素
            iteratorJdk.forEachRemaining(ele -> System.out.println(ele));
    
        }
    
    }
    
    Arraylist聚合对象有:
    老王
    小王
    小张
    

    正常情况下,会打印两次集合对象中的信息,实际上只打印了一次,正是由于next调用过的元素,forEachRemaining不会再调。

    四、总结

    当一个对象是一个聚合对象且需要对外提供遍历方法时,可以使用迭代器模式。

    迭代方式提供了不同的方式遍历聚合对象,增加新的聚合类和迭代器类都是比较方便的,Java集合类中庞大的家族采用迭代器模式就是基于这种优点。

    迭代器模式有设计模式的通用缺点——系统复杂性,迭代器模式将数据存储和数据遍历分开,增加了类的个数。

    整体来说,迭代器模式是比较易于理解的一种行为型设计模式

  • 相关阅读:
    100天精通Python——第39天:操作MySQL和SqlServer
    AI:141-利用自然语言处理改进医疗信息提取与分类
    用python混合检索 + 重排序改善
    DSPE-PEG-amine 474922-26-4 生物分子修饰磷脂-聚乙二醇-氨基
    支持Unicode的Java正则表达式?
    鸿蒙DevEco Studio 4.1 Release-模拟器启动方式错误
    Vue中v-on的基础用法、参数传递和修饰符
    【MySQL进阶】深入理解InnoDB数据页结构
    表单规定输入域的选项列表(html5新元素)
    【QT 5 +Linux下软件qt软件打包+qt生成软件创建可以安装压缩包+学习他人文章+第三篇:学习打包】
  • 原文地址:https://blog.csdn.net/m0_73257876/article/details/126846445
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号