首页 > 其他分享 >迭代器模式

迭代器模式

时间:2024-01-24 14:48:16浏览次数:28  
标签:return 迭代 对象 模式 集合 public objArr

遍历集合用的,不暴露集合的内部表示,但又能顺序访问内部的元素

  • 定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示
  • 类型:行为型
  • 适用场景:
    • 访问一个集合对象的内容而无需暴露它的内部表示
    • 为遍历不同的集合结构提供一个统一的接口
  • 优点:分离了集合对象的遍历行为
  • 缺点:类的个数成对增加
  • 相关的设计模式:
    • 迭代器模式和访问者模式:都是迭代的访问集合对象中的元素,不同的是,在访问者模式当中扩展开放的部分作用于对象的操作上,而迭代器模式中扩展开放的部分是在集合对象的种类上,这两者的实现方式有很大的区别

coding

/**
 * <p>抽象出来一个聚集类 == 提供创建集合对象迭代器的一系列抽象方法</p>
 *
 */
public abstract class AbstractAggregate {

    /**
     * <p>创建聚集对象的迭代器 == 使用迭代器对集合进行相关操作</p>
     *
     * @return 对象的迭代器
     */
    public abstract IIterator createIterator();

    /**
     * <p>返回聚集对象(集合、迭代器对象)包含的对象(元素)的大小</p>
     *
     * @return 大小
     */
    public abstract int size();

    /**
     * <p>聚集对象包含的元素是否为空</p>
     *
     * @return 空(true)不空(false)
     */
    public abstract boolean isEmpty();

}
/**
 * <p>自定义集合类,实现聚集抽象类中的迭代器的创建方法</p>
 *
 */
public class MyCollection extends AbstractAggregate {

    /**
     * 集合的底层用的就是数组
     */
    Object[] objArr;

    public MyCollection(Object[] objArr) {
        this.objArr = objArr;
    }

    @Override
    public IIterator createIterator() {
        /**
         * 将当前集合对象作为参数,调用迭代器的构造函数
         * 注意,该方法的NB之处,就是同一个聚集对象可以new出来好多个迭代器
         * 虽然,上面一段话说出来跟没说一样,但是博主还是想傻傻的强调一下
         */
        return new MyIterator(this);
    }

    @Override
    public int size() throws NullPointerException {
        if (objArr == null) {
            throw new NullPointerException("objArr is null !");
        }
        return objArr.length;
    }

    @Override
    public boolean isEmpty() throws NullPointerException {
        if (objArr == null) {
            throw new NullPointerException("objArr is null !");
        }
        return objArr.length == 0;
    }

    public Object[] getObjArr() {
        return objArr;
    }

    public void setObjArr(Object[] objArr) {
        this.objArr = objArr;
    }
}
/**
 * <p>迭代器接口</p>
 *
 */
public interface IIterator {

    /**
     * <p>当前迭代器中是否还有元素</p>
     *
     * @return 有(true) 没有(false)
     */
    boolean hasNext();

    /**
     * <p>取出迭代器中的元素</p>
     *
     * @return 对象
     */
    Object next();

    /**
     * <p>取出迭代器中的第一个元素</p>
     *
     * @return 第一个元素
     */
    Object first();

}
/**
 * <p>自定义迭代器,实现迭代器接口中的所有方法</p>
 *
 */
public class MyIterator implements IIterator {

    /**
     * 迭代器的目标对象,就是集合
     */
    private MyCollection collection;

    /**
     * 这里保留一份集合对象包含的元素的大小
     */
    private int size;

    /**
     * 记录元素的位置
     */
    private int pos = 0;

    public MyIterator(MyCollection collection) {
        this.collection = collection;
        this.size = collection.size();
    }

    @Override
    public boolean hasNext() {

        /**
         * (1)只要size不等于pos初始化时候的0,集合里肯定是有元素的
         * (2)返回true的时候,一定不要忘了让pos往后移,这就是迭代器只能使用一次的原因所在
         * (3)如果想复用迭代器,调用first函数,重置pos位置的值
         */
        if (pos < size) {
            pos++;
            return true;
        }
        return false;

    }

    @Override
    public Object next() {
        return collection.getObjArr()[pos - 1];
    }

    @Override
    public Object first() {
        pos = 0;
        return collection.getObjArr()[0];
    }
}

 

UML

测试

/**
 * <p>迭代子模式测试 == 典型的类似集合的方式实现了我们自己的迭代器,通过迭代器实现元素的遍历</p>
 *
 */
public class IteratorTest {

    public static void main(String[] args) {
        myIterator();
    }

    private static void myIterator() {

        Integer[] numArr = new Integer[]{1, 2, 3};
        AbstractAggregate aggregate = new MyCollection(numArr);
        IIterator iterator = aggregate.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        System.out.println("==============若想要迭代器继续迭代输出元素");
        System.out.println("first = " + iterator.first());
        System.out.println("==============我们可以调用first方法重置pos");

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

        System.out.println("==============我们再来创建一个迭代器对象出来");
        IIterator iteratorOther = aggregate.createIterator();
        while (iteratorOther.hasNext()) {
            System.out.println(iteratorOther.next());
        }

    }

    /**
     * <p>描述迭代子模式:</p>
     * 迭代子模式又叫游标模式,是对象的行为模式。
     * 迭代子模式可以顺序的访问一个聚集中的元素而不必暴露聚集内部表象。
     *
     *  优点:
     *  (1)本来聚集类要干的事情,分担给具体的迭代器类了,聚集类和迭代器实现了很好的解耦,
     *       这样一来,迭代的算法可以完全独立于聚集类;
     *  (2)一个聚集类的对象,也就是聚集对象,可以创建出N个迭代器,同时进行元素迭代而互不干扰
     */

}
=========输出结果=========
1
2
3
==============若想要迭代器继续迭代输出元素
first = 1
==============我们可以调用first方法重置pos
1
2
3
==============我们再来创建一个迭代器对象出来
1
2
3

 

源码中的应用

  • java.util.Iterator:可以看它里面的方法
  • IMG_256

标签:return,迭代,对象,模式,集合,public,objArr
From: https://www.cnblogs.com/wangzhilei-src/p/17984610

相关文章

  • CS与BS架构模式概述
    ###CS(ClientServer):客户端服务器架构优点:利用客户端机器的资源,减轻服务器的负荷;一部分安全要求不高的计算任务、存储任务都会放在客户端执行,不需要把所有的计算和存储都放在服务器执行,减轻服务器压力,也减轻网络访问速度。缺点:需要安装本地客户端,后期升级维护成本高。适用......
  • H3C的设备如何从云模式转到FIT 模式
    1.说明[58c7-ac95-7b40]ap-mode?anchor-acSettheAPmodetoanchorACanchor-fitSettheAPmodetoanchorFITcloudSettheAPmodetocloudAPfatSettheAPmodetofatAPfitSettheAPmodetofitAP2.案例实验(设备连接拓......
  • C# Switch 语句进阶:模式匹配详解与实例演示
     在C#中,switch语句的模式匹配在C#7.0及以上版本中引入。以下是switch语句中常见的模式及其使用方法的示例:1.类型模式:优点: 用于检查对象的运行时类型,使代码更具可读性。publicstaticstringGetObjectType(objectobj){switch(obj){caseinti:......
  • 设计模式
    ///<summary>///PLC处理器///</summary>publicinterfaceIPlcHandler{voidRequest(IPlcContextcontext);}///<summary>///PLC的数据上下文///</summary>publicinterfaceIPlcContext{PlcRequestRequest{get;}......
  • 策略模式【结合springboot实现】
    Hello!~大家好啊,很高兴我们又见面了,今天我们一起学习设计模式–【策略模式】初次对此模式不懂的,或者想偷懒的,我强烈建议大家跟着我的一起把概念和代码一起敲一遍!~为啥子??因为我就是这样学会的,哈哈哈!1.首先我们看下此模式的整体UML图selector:选择器又叫做上下文conte......
  • 设计模式之模板方法
    1.定义定义了一个算法的框架,并允许子类重写其中的某些步骤,而不改变算法的结构2.口语化表述模板方法其实在日常生活中已经很常见,所谓模板方法,就是事先约定好一些事情,后续做时再慢慢实现或者修改,比如组装电脑假设现在需要组装一台台式电脑,一开始计划使用3090显卡,后来根据实际......
  • 策略模式
    if...else...的优雅写法,可以配合委托模式一起使用定义:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户补充定义:处理大量if...else...代码类型:行为型适用场景:系统有很多类,而他们的区别仅仅在于他们的行为策略不同一个系统需......
  • 生成器 迭代器 可迭代对象 深拷贝浅拷贝 闭包 装饰器 正则
    ​ python的导包python采用的导包方式有多种如:importx(包名)     比如导包时importhashlib调用时hashlib.md5("123456".encode("utf-8"))     importx(包名).xxx(方法名)         比如导包时importos.path调用时path.join(postion,......
  • Nginx配置ThinkPHP3.1的PATHINFO模式
    server{listen8156;#监听端口(根据自己的需求更改)server_namelocalhost;#域名root/www/php;indexindex.htmlindex.htmindex.php;location~.*\.php/?.*${fastcgi_indexindex.php;fastcgi_pass127.0.0.1:9000;includefa......
  • Appium PO模式UI自动化测试框架——设计与实践
    AppiumPO模式UI自动化测试框架——设计与实践1.目的  相信做过测试的同学都听说过自动化测试,而UI自动化无论何时对测试来说都是比较吸引人的存在。相较于接口自动化来说它可以最大程度的模拟真实用户的日常操作与特定业务场景的模拟,那么存在即合理,自动化UI测试自然也是广......