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

设计模式 17 迭代器模式

时间:2022-08-14 18:22:31浏览次数:86  
标签:遍历 17 迭代 数组 array 设计模式 ArrayCollection String

参考源

https://www.bilibili.com/video/BV1u3411P7Na?p=25&vd_source=299f4bc123b19e7d6f66fefd8f124a03


迭代器模式(Iterator Pattern)属于行为型模式

概述

迭代器模式是 Java 中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,而不需要知道集合对象的底层表示。

迭代器是学习 Java 语言的基础,没有迭代器,集合类的遍历就成了问题,正是因为有迭代器的存在,才能更加优雅的使用 foreach 语法。

Java 中的增强 for 循环是使用迭代器实现的

List<String> list = Arrays.asList("AAA", "BBB", "CCC");
// 使用 foreach 语法糖进行迭代,依次获取每一个元素
for (String s : list) {
    
    // 打印元素
    System.out.println(s);
}

编译之后的代码如下:

List<String> list = Arrays.asList("AAA", "BBB", "CCC");
// 这里本质是通过 List 生成的迭代器来遍历每个元素的
Iterator var2 = list.iterator();
// 判断是否还有元素可以迭代,没有就返回false
while(var2.hasNext()) {
    
    // 通过 next 方法得到下一个元素,每调用一次,迭代器会向后移动一位
    String s = (String)var2.next();
    // 打印元素
    System.out.println(s);
}

可以看到,当使用迭代器对 List 进行遍历时,实际上就像是在操作一个指向列表头部的指针,通过不断向后移动指针来依次获取所指向的元素。

image-20220525171535024

image-20220525171557523

代码实现

这里依照 JDK 提供的迭代器接口(JDK 已经定义好了一个迭代器的具体相关操作接口),也来设计一个迭代器:

1、定义数组集合

/**
 * 数组集合<br>
 * 实现 Iterable 接口表示此类是支持迭代的
 */
public class ArrayCollection<T> implements Iterable<T> {

    /**
     * 使用数组来存放数据
     */
    private final T[] array;

    /**
     * 构造器私有,自己用
     * @param array 数组
     */
    private ArrayCollection(T[] array) {
        this.array = array;
    }

    /**
     * 使用静态方法获取对象
     * @param array 数组
     * @return 数组集合对象
     * @param <T> 实体类
     */
    public static <T> ArrayCollection<T> of(T[] array) {
        return new ArrayCollection<>(array);
    }

    /**
     * 实现 iterator 方法,此方法会返回一个迭代器,用于迭代我们集合中的元素
     * @return 迭代器
     */
    @Override
    public Iterator<T> iterator() {
        return new ArrayIterator();
    }

    /**
     * 这里自定义 ArrayIterator,注意别用静态,需要使用对象中存放的数组
     */
    public class ArrayIterator implements Iterator<T> {
        
        // 这里通过指针表示当前的迭代位置
        private int index = 0;

        /**
         * 判断是否还有下一个元素
         * @return 结果
         */
        @Override
        public boolean hasNext() {
            
            // 如果指针大于或等于数组最大长度,就不能再继续了
            return index < array.length;
        }

        /**
         * 返回当前指针位置的元素并向后移动一位
         * @return
         */
        @Override
        public T next() {
            
            // 正常返回对应位置的元素,并将指针自增
            return array[index++];   
        }
    }

}

2、调用

// 定义数组
String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
// 使用数组集合处理数组
ArrayCollection<String> collection = ArrayCollection.of(arr);
// 使用 foreach 语法糖遍历,最后还是会变成迭代器调用
for (String s : collection) {
    System.out.println(s);
}

编译后的代码为:

String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
ArrayCollection<String> collection = ArrayCollection.of(arr);
// 首先获取迭代器,实际上就是调用我们实现的 iterator 方法
Iterator var3 = collection.iterator();

while(var3.hasNext()) {
    // 使用 next() 方法不断向下获取
    String s = (String)var3.next();
    System.out.println(s);
}

输出结果为:

AAA
BBB
CCC
DDD

这样就实现了自定义迭代器来遍历数组。

优缺点

优点

1、它支持以不同的方式遍历一个聚合对象。

2、迭代器简化了聚合类。

3、在同一个聚合上可以有多个遍历。

4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点

由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

使用场景

1、访问一个聚合对象的内容而无须暴露它的内部表示。

2、需要为聚合对象提供多种遍历方式。

3、为遍历不同的聚合结构提供一个统一的接口。

标签:遍历,17,迭代,数组,array,设计模式,ArrayCollection,String
From: https://www.cnblogs.com/codesail/p/16585964.html

相关文章

  • NC17193 简单瞎搞题
    题目链接题目题目描述一共有n个数,第i个数是xixi可以取[li,ri]中任意的一个值。设\(S=\sum{{x_i}^2}\),求S种类数。输入描述第一行一个数n。然后n......
  • 设计模式 16 命令模式
    参考源https://www.bilibili.com/video/BV1u3411P7Na?p=24&vd_source=299f4bc123b19e7d6f66fefd8f124a03命令模式(CommandPattern)属于行为型模式概述现在各大电子......
  • Solution -「NOI 2017」「洛谷 P3825」游戏
    \(\mathscr{Description}\)  Link.  给大家看个乐子:link,懒得概括题意啦.\(\mathscr{Solution}\)  对于没有X的情况,显然可以2-SAT;对于有X的情况,暴......
  • Solution -「NOI 2017」「洛谷 P3822」整数
    \(\mathscr{Description}\)  Link.  初始有整数\(x=0\),给出\(n\)次操作,每次操作为\(x\getsx+a\cdot2^b\)或询问\(x\)的第\(k\)bit.  \(n\le10^6\),......
  • 2022.8.17 vscode与nodejs
    大前端01、概述和前端工具vscode安装1.1、下载安装VScode下载地址:https://code.visualstudio.com/   1:双击打开vscode安装包2:指定安装目录     ......
  • org.elasticsearch.transport.RemoteTransportException: [fort2][172.100.4.25:9300]
    elasticsearch报错[2022-08-06T23:00:05,943][INFO][o.e.c.c.JoinHelper][fort1]failedtojoin{fort2}{nR7UstreQIe_yKXlxpo-Ew}{XRdOsMHwTnafWK9SD943Gg}{1......
  • 读取mini-imagnet图片并将其转为可迭代对象训练神经网络
    da=torchvision.transforms.Compose([torchvision.transforms.ToTensor()])#必须有这步否则会出现default_collate:batchmustcontaintensors,numpyarrays,numbers......
  • CF1712题解(E,F)
    E题意是让你求满足\(lcm(i,j,k)\geqi+j+k\)的三元组个数。我们通常都有一个直观感觉,lcm应该是各数之积级别的,换句话说,不满足\(lcm(i,j,k)\geqi+j+k\)的三元组个数......
  • 【luogu CF1710B】Rain(差分)(性质)
    Rain题目链接:luoguCF1710B题目大意给你若干个函数,每个函数是一个45度往上线段和往下线段接在一起,两个长度一样,y轴从0出发的。然后对于每个函数,求把它以外的所有......
  • 迭代器与生成器
    1.什么是迭代器迭代器是用来迭代取值的工具,而迭代的意思是一个重复的过程,每一次的重复都是基于上一次的结果继续的,单纯的重复并不是迭代2.为何要有迭代器在python中涉及......