设计模式-迭代器模式

设计模式系列(十三)迭代器模式(Iterator Pattern) 设计模式系列(十三)迭代器模式(Iterator Pattern)     迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露器内部的表示。也就是说,迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部的表示,把游走的任务放在迭代器上,而不是聚合上,这样就简化了聚合的接口和实现,也让责任各得其所。     学过面向对象编程语言的朋友一定对迭代器这个设计深有 阅读详情

迭代器模式

定义

  • 迭代器模式又称为游标模式
  • 它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节本质
    • 什么是容器,能够容纳对象的所有类型的都可以称为容器
      • Collection集合类型
      • Set类型
      • 等
  • 抽离集合对象迭代行为到迭代器中,提供一致的访问接口

组合模式也是为了提供一致的访问接口,关心整体和个体一致

属于行为型模式

生活中的例子

  • 快递迭代分发
  • 刷脸刷票进展

适用场景

  1. 访问一个集合对象的内容不需要暴露他的内部表示
  2. 为遍历不同的集合结构提供统一的方式

通用结构

image-20210106225330851

角色说明

Iterator抽象迭代器

​ 抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的两个方法

  • next
  • hasNext(判断是否已经访问到底部
public interface Iterator<E> {

    E next();

    boolean hasNext();
}
ConcreteIterator具体迭代器

迭代器的实现,主要用来完成容器元素的遍历

public class ConcreteIterator<E> implements Iterator<E> {
  private List<E> list;
  private int cursor = 0;

  public ConcreteIterator(List<E> list) {
    this.list = list;
  }


  public E next() {
    return this.list.get(this.cursor ++);
  }


  public boolean hasNext() {
    return this.cursor < this.list.size();
  }
}
Aggregate抽象容器

​ 容器角色负责提供创建具体迭代器角色的接口

iterator

public interface IAggregate<E> {
  boolean add(E element);

  boolean remove(E element);

  Iterator<E> iterator();
}
Concrete Aggregate具体容器

​ 具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。

public class ConcreteAggregate<E> implements IAggregate<E> {
  private List<E> list = new ArrayList<E>();

  public boolean add(E element) {
    return this.list.add(element);
  }

  public boolean remove(E element) {
    return this.list.remove(element);
  }

  public E get(int index)
  {
    return this.list.get(index);
  }

  public Iterator<E> iterator() {
    return new ConcreteIterator<E>(this.list);
  }

  public int size()
  {
    return list.size();
  }
}

测试

public class Test {
    public static void main(String[] args) {
        //来一个容器对象
        IAggregate<String> aggregate = new ConcreteAggregate<String>();
        //添加元素
        aggregate.add("one");
        aggregate.add("two");
        aggregate.add("three");
        //获取容器对象迭代器
        Iterator<String> iterator = aggregate.iterator();
        //遍历
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }

    }
}

注意:开发系统时,迭代器的删除方法应该完成两个逻辑

  • 一是删除当前元素
  • 二是当前游标指向下一个元素

关于泛型的说明

上面看到了E大家肯定都有疑问

我们对大部分用到的泛型都列一下

  • E
    • Element
    • 代表一个类型,具体是什么类型是在实现或者运行的时候觉得
  • T
    • Type
    • 类的操作类型
  • K
    • Key
  • V
    • Value
  • ?
    • 啥都行
    • <? extends IMember>

都是一样的,占位,不要做强制=转型

源码中的实现

JDK中的Iterator

public interface Iterator<E> {

  boolean hasNext();


  E next();

  default void remove() {
    throw new UnsupportedOperationException("remove");
  }

  default void forEachRemaining(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    while (hasNext())
      action.accept(next());
  }
}

ArrayList的迭代器

private class Itr implements Iterator<E> {
  int cursor;       // index of next element to return
  int lastRet = -1; // index of last element returned; -1 if no such
  int expectedModCount = modCount;

  Itr() {}

  public boolean hasNext() {
    return cursor != size;
  }

  @SuppressWarnings("unchecked")
  public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
      throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
      throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
  }

  public void remove() {
    if (lastRet < 0)
      throw new IllegalStateException();
    checkForComodification();

    try {
      ArrayList.this.remove(lastRet);
      cursor = lastRet;
      lastRet = -1;
      expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
      throw new ConcurrentModificationException();
    }
  }

可以看到对应的迭代器实现了HasNext,next,remove方法

FailFast

看到ArrayList的iterator可以看到返回了迭代器Itr

public Iterator<E> iterator() {
  return new Itr();
}

image-20210108234119001

可以看到java.util.ArrayList.Itr#next,当i的长度大于当前ArrayList内部的数组的长度的时候就会抛出ConcurrentModificationException,那么什么情况才会这样呢,当我们在使用迭代器遍历的时候,容器的数据结构变更了,此时我们如果继续遍历很有可能出现问题,所以通过FailFast抛出异常来避免我们使用错误的数据结果

public E next() {
  checkForComodification();
  int i = cursor;
  if (i >= size)
    throw new NoSuchElementException();
  Object[] elementData = ArrayList.this.elementData;
  if (i >= elementData.length)
    throw new ConcurrentModificationException();
  cursor = i + 1;
  return (E) elementData[lastRet = i];
}

测试代码如下

public class FailFastTest {
  public static void main(String[] args) {
    ArrayList<Integer> lists = initList(10);

    Iterator<Integer> iterator = lists.iterator();
    int count = 0;
    while (iterator.hasNext()) {
      lists.remove(0);
      if (count == 3) {
      }
      System.out.println(iterator.next());
      count++;
    }
  }

  private static ArrayList<Integer> initList(int count) {
    ArrayList<Integer> list = new ArrayList<>();
    for (int i = 1; i < count; i++) {
      list.add(i);
    }
    return list;

  }
}

抛出异常

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.zzjson.design.pattern.iterator.failfast.FailFastTest.main(FailFastTest.java:27)

HashMap中的迭代器

    final class KeyIterator extends HashIterator
        implements Iterator<K> {
        public final K next() { return nextNode().key; }
    }

    final class ValueIterator extends HashIterator
        implements Iterator<V> {
        public final V next() { return nextNode().value; }
    }

    final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }
abstract class HashIterator {
  public final boolean hasNext() {
    return next != null;
  }

  public final void remove() {
    Node<K,V> p = current;
    if (p == null)
      throw new IllegalStateException();
    if (modCount != expectedModCount)
      throw new ConcurrentModificationException();
    current = null;
    K key = p.key;
    removeNode(hash(key), key, null, false, false);
    expectedModCount = modCount;
  }
}

可以看到提供了三种迭代器都提供了next方法,hasNext和remove都是从父类中继承的

  • 可以看到这也是模板方式的使用,设计模式不是固定用什么设计模式,而是取决于什么场景适用什么设计模式

Mybatis DefaultCursor

可以看到Mybatis的内部类也提供了对应的迭代器


private class CursorIterator implements Iterator<T> {


  T object;


  int iteratorIndex = -1;

  @Override
  public boolean hasNext() {
    if (object == null) {
      object = fetchNextUsingRowBound();
    }
    return object != null;
  }

  @Override
  public T next() {
    T next = object;

    if (next == null) {
      next = fetchNextUsingRowBound();
    }

    if (next != null) {
      object = null;
      iteratorIndex++;
      return next;
    }
    throw new NoSuchElementException();
  }

  @Override
  public void remove() {
    throw new UnsupportedOperationException("Cannot remove element from Cursor");
  }
}

优缺点

优点

  • 多态迭代
  • 简化集合对象接口
  • 元素迭代功能多样化
  • 解耦迭代和计划

缺点

数组,有序列表,使用迭代器方式遍历较为繁琐

日出开发中,我们几乎不会自己写迭代器,除非我们需要定制一个自己的数据结构对应的迭代器,否则,开源框架提供给我们的API完全够用 我的笔记仓库地址gitee 快来给我点个Star吧

【Java设计模式】Java设计模式之(八)迭代器模式(Iterator Pattern) 本文目录 一、迭代器概述 1.1 优缺点 1.2 使用场景 1.3 注意事项 二、代码实现 2.1 通用类图 2.2 代码实现 迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。迭代器模式属于行为型模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 一、迭代器概述 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。 主要解决:不同的方式来遍历整个整合对象。 何时使用:遍历一个聚 阅读详情

相关推荐

删除win10电脑U盘使用记录

手工删除:和查看的方法类似,分三步,缺一不可,顺序也不能反! 第一步 设置环境变量,变量名为“devmgr_show_nonpresent_devices”,值为“1”。 第二步 打开设备管理器,勾上“查看”菜单中的“显示隐藏设备”。如果之前已经打开设备管理器,则要关了,重新打开。 第三步 清除“磁盘驱动器”、“存储卷”、“通用串行总线控制器”3个栏目下所有的灰色的图标,注意是所有!右键点击灰色图标,然后选择“卸载”。 成功 :结果USBSTOR 没有了 ...

qq_40544338的博客 2万+

您的设计模式——迭代器模式【Iterator Pattern】

周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 C,老大站在背后,赶忙站起来, “王经理,你找我?” 我说。“哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。 到老大办公室,“是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着也有点糊涂,你看,这是我们现在还在开发或者维护的 103 个项目,你能不能先把这些项目信息重

557

GB/T 27930-2023协议升级与CANoe仿真测试实践

本文深入解析GB/T 27930-2023协议的核心升级,包括A/B类系统分类与EVIN码引入,并详细指导如何使用CANoe搭建仿真测试环境、编写CAPL脚本及利用DLL库进行一致性验证与故障注入测试,助力开发人员确保电动汽车充电通信的合规性与稳定性。

y7z8a的博客 540

设计模式迭代器模式(IteratorPattern)

核心模块:迭代器角色(定义访问和遍历元素的接口),具体迭代器角色,容器角色,具体容器角色 所有代码请访问:git@code.aliyun.com:289804201/PatternLearn.git 使用场景:外部对象访问内部聚合对象; 优点:将存储数据和遍历数据分开,符合单一职责原则; 缺点:新聚合类,就要增加新的迭代器类;增加系统复杂性; /** * C

didiao11300的专栏 723

TLV320AIC3204音频CODEC硬件设计与调试实战

本文深入解析了TLV320AIC3204音频CODEC的硬件设计与调试实战。文章从芯片功能定位入手,详细阐述了电源时钟设计、模拟输入电路等关键硬件设计要点,并提供了软件驱动配置与分层调试方法,帮助工程师有效规避常见陷阱,解决底噪、失真等典型音频调试问题。

zero1的博客 1123

Claude Code 处理长任务 + Cursor 专注交互:双栈协作的 3 种分工场景与响应提速 35% 实测

揭示 Claude Code 与 Cursor 在 AI 编程中的本质分工:Claude Code 作为离线式架构师处理跨文件、带约束的长链路重构(如单体拆微服务),Cursor 作为现场交互工程师专注秒级局部编辑;提出按任务切片动态切换的三种工程化协作场景,并给出结构化上下文构建、约束型 Prom

weixin_28728443的博客 123

23种设计模式之迭代器模式(Iterator Pattern)

本篇文章将23种设计模式中的迭代器模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

logisim中,如何设计一个位于十字路口的交通信号灯控制系统?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1342

设计模式(Design pattern)之迭代器模式(Iterator Pattern)

本文介绍了Java中的迭代器设计模式实现。迭代器模式提供了一种顺序访问聚合对象元素的方法,同时隐藏其内部结构。文章展示了完整的代码示例,包括抽象迭代器接口(MachineIterator)、聚合角色接口(MachineGather)及其实现类(MachineGatherImpl)。具体实现中,Machine类表示设备对象,MachineImpl类实现了迭代器逻辑,通过hasNext()和next()方法遍历集合。最后通过CustomerRun类的main方法演示了如何使用迭代器遍历设备集合。该模式属于行为型

RR1335 之代码才是动力源 260

【PINN高级教程】范式融合与前沿应用 第5讲:贝叶斯推断与生成式建模的深度融合

正规化流(Normalizing Flow, NF)通过一系列可逆变换把简单分布映射为复杂后验,从而获得更好的表达能力。算子学习保持映射的物理正确性。贝叶斯推断给出了自然的框架,但直接对高维函数空间做采样(如 MCMC)几乎不可行。1️⃣ 在自己的 PDE 上跑一遍完整的 Bayesian PINN 流模型。的学习机制深度融合,以在保持物理一致性的前提下,高效地从后验分布中采样。2️⃣ 将每个 θ 直接映射到 FNO 权重,得到不同解的采样。的后验 p(θ∣x,y)p(θ∣x,y) 进行近似。

u012133341的博客 474

【Halcon-2D测量】set_metrology_object_param 函数功能(用于配置计量对象常规参数)

HALCON算子 set_metrology_object_param 是2D计量模块的核心配置工具,用于动态修改计量对象的测量区域、边缘检测和几何拟合参数。该算子需在检测前调用,支持批量或单独修改对象参数,包含三类关键参数:测量区域(如长度、间距)、边缘检测(如平滑Sigma、阈值)和几何拟合(如RANSAC阈值、最小分数)。使用时需注意参数互斥规则(如measure_distance优先于num_measures)和多线程同步要求。算子无输出参数,仅修改计量模型内部状态,需配合apply_metrolo

weixin_45590420的博客 291

设计模式之迭代器模式

简介:迭代器模式(Iterator Pattern)是 行为型模式。它可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。 优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。 缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应...

倪先生的博客 129

SAP S/4HANA 数据 API 化与 MCP 集成全流程实战指南

通过 RAP 发布 OData、利用 Communication Arrangement 打通外网、再在 MCP-server 里封装函数签名,你就能把 S/4HANA 的核心数据安全、标准化地暴露给任意支持 MCP 的大模型。这条链路的每一个环节都由 SAP 与 MCP 社区提供了现成框架,既兼顾了企业合规,也让 LLM 落地更为轻量。期待你在项目里把这些拼图真正串联起来,让业务数据与生成式 AI 碰撞出高价值的火花。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 976

【设计模式】GoF设计模式之迭代器模式(Iterator Pattern)

迭代器模式是一种行为型设计模式,其核心思想是由业务类生成一个迭代器,通过迭代器可以以某种逻辑遍历,访问业务类实例中特定集合中的元素。 业务类实例中的集合可以有不同的遍历逻辑,对于不同的遍历逻辑,可以生成不同的迭代器。

YoseZang的博客 809

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java设计模式——迭代器模式【Iterator Pattern】

Java设计模式、迭代器模式、Iterator Pattern

scorpio的博客 503

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

设计模式-迭代器模式(Iterator Pattern)

迭代器模式 定义 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。 类型 行为型。 角色 抽象迭代器(Iterator):抽象迭代器负责定义访问和遍历元素的接口。 具体迭代器(ConcreteIterator):提供具体的元素遍历行为。 抽象容器(Aggregate):负责定义提供具体迭代器的接口。 具体容器(ConcreteAggregate):创建具体...

kaven 1643

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

23种设计模式——迭代器模式 (Iterator Pattern)详解

本文介绍了23种设计模式之——迭代器模式 (Iterator Pattern)的说明及使用

Meteors.的博客 980

设计模式:迭代器模式(Iterator Pattern)

迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。

TechNomad的博客 838

【设计模式】——迭代器模式(Iterator Pattern)

迭代器模式(Iterator Pattern)是一种行为设计模式,它为访问一个聚合对象(如列表、集合等)中的元素提供了一种统一的方法,同时又不暴露其内部表示。通过迭代器模式,算法与聚合对象的结构相分离,增加了代码的灵活性和可重用性。

J^T的博客 1162

设计模式之 迭代器模式(Iterator Pattern) Java实现

  所谓迭代器模式,就是把集合的数据和遍历分开 让遍历集合依赖于迭代器,而不依赖于具体的集合 从而可以达到代码复用 java中的增强for循环就是迭代器模式的应用,要使用增强for循环语法的集合,就要实现java.util.Iterator接口。 在迭代器模式中,需要几个角色 Iterator(迭代器) ConcreteIterator(具体的迭代器) Aggregate(集合) ...

Lu_1u的博客 546

设计模式-迭代器模式-Iterator Pattern

是一种提供共享所有权(shared ownership)的互斥量,它允许多个线程同时获取共享锁(shared lock),进行读操作,或者独占锁(unique lock),进行写操作。迭代器模式(Iterator Pattern)是一种常用的设计模式,它在软件开发中用于顺序访问一个聚合对象中的各个元素,而不需要暴露其内部的表现。迭代器模式的应用场景非常广泛,它的核心价值在于提供了一种抽象和解耦的方式,使得客户端代码可以独立于数据结构的具体实现,从而提高了代码的灵活性和可维护性。

wesigj的博客 1897

设计模式 18 迭代器模式 Iterator Pattern

迭代器模式 (Iterator Pattern) 是一种行为型设计模式,它提供了一种访问集合元素的标准方法,而无需暴露集合的内部表示。提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。核心思想来自将遍历集合的逻辑从集合本身中分离出来,封装到一个独立的迭代器对象中。迭代器对象负责维护遍历的当前位置,并提供访问下一个元素的方法。想象一个书架,上面摆满了书籍。直接访问: 你直接走到书架前,从最左边开始一本一本地拿书阅读。

jxusthusiwen的专栏 1609

设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码

用于顺序访问集合对象的元素,使用者不需要知道集合对象的底层表示。

码鹿的记录 1099

设计模式之迭代器模式详解(Iterator Pattern)

认识迭代器模式 在系统开发中,集合对象内部表示各不相同。底层构造也尽不相同。对于这些对象,我们希望在不暴露其底层和内部表示的同时,可以使外部客户访问其中元素。 迭代器模式就为这一需求提供了极其优雅的实现,接下来就让我们来认识认识迭代器模式: 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。 迭代器模式(Iterato...

Superman_peng的博客 537

设计模式教程:迭代器模式(Iterator Pattern)

提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示。

遇见伯灵说的博客 1042
上一篇: 设计模式-责任链模式
下一篇: 设计模式-命令模式
黄金时代的架构之路
博客等级 码龄12年 540粉丝 127原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值