• 设计模式 17 迭代器模式


    参考源

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


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

    概述

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

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

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

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

    编译之后的代码如下:

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

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

    image-20220525171535024

    image-20220525171557523

    代码实现

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

    1、定义数组集合

    1. /**
    2. * 数组集合
    3. * 实现 Iterable 接口表示此类是支持迭代的
    4. */
    5. public class ArrayCollection implements Iterable {
    6. /**
    7. * 使用数组来存放数据
    8. */
    9. private final T[] array;
    10. /**
    11. * 构造器私有,自己用
    12. * @param array 数组
    13. */
    14. private ArrayCollection(T[] array) {
    15. this.array = array;
    16. }
    17. /**
    18. * 使用静态方法获取对象
    19. * @param array 数组
    20. * @return 数组集合对象
    21. * @param 实体类
    22. */
    23. public static ArrayCollection of(T[] array) {
    24. return new ArrayCollection<>(array);
    25. }
    26. /**
    27. * 实现 iterator 方法,此方法会返回一个迭代器,用于迭代我们集合中的元素
    28. * @return 迭代器
    29. */
    30. @Override
    31. public Iterator iterator() {
    32. return new ArrayIterator();
    33. }
    34. /**
    35. * 这里自定义 ArrayIterator,注意别用静态,需要使用对象中存放的数组
    36. */
    37. public class ArrayIterator implements Iterator {
    38. // 这里通过指针表示当前的迭代位置
    39. private int index = 0;
    40. /**
    41. * 判断是否还有下一个元素
    42. * @return 结果
    43. */
    44. @Override
    45. public boolean hasNext() {
    46. // 如果指针大于或等于数组最大长度,就不能再继续了
    47. return index < array.length;
    48. }
    49. /**
    50. * 返回当前指针位置的元素并向后移动一位
    51. * @return
    52. */
    53. @Override
    54. public T next() {
    55. // 正常返回对应位置的元素,并将指针自增
    56. return array[index++];
    57. }
    58. }
    59. }

    2、调用

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

    编译后的代码为:

    1. String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
    2. ArrayCollection collection = ArrayCollection.of(arr);
    3. // 首先获取迭代器,实际上就是调用我们实现的 iterator 方法
    4. Iterator var3 = collection.iterator();
    5. while(var3.hasNext()) {
    6. // 使用 next() 方法不断向下获取
    7. String s = (String)var3.next();
    8. System.out.println(s);
    9. }

    输出结果为:

    1. AAA
    2. BBB
    3. CCC
    4. DDD

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

    优缺点

    优点

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

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

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

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

    缺点

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

    使用场景

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

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

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

  • 相关阅读:
    python yaml库:safe_load()(安全解析函数,解析yaml)(防止yaml文件中包含恶意代码)
    package ‘XXXX’ is not available (for R version 3.6.0) 解决R版本适配的问题
    Jest 学习笔记
    你能猜出这是什么代码
    Effective C++ 规则29:为“异常安全”而努力是值得的
    java毕业设计汽车租赁系统Mybatis+系统+数据库+调试部署
    21、Flink 大状态调优
    yolov5使用GPU
    认识BIOS基本输入输出系统
    Auto-WEKA(Waikato Environment for Knowledge Analysis)
  • 原文地址:https://blog.csdn.net/qq_37770674/article/details/126335013