设计模式-迭代器模式

设计模式系列(十三)迭代器模式(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 编程环境中非常常用的设计模式。迭代器模式属于行为型模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 一、迭代器概述 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。 主要解决:不同的方式来遍历整个整合对象。 何时使用:遍历一个聚 阅读详情

相关推荐

避坑指南:PyCINRAD处理CINRAD雷达数据时遇到的5个典型报错及解决方案

本文针对使用PyCINRAD库处理CINRAD雷达基数据时常见的5个典型报错,提供了详细的解决方案。内容涵盖环境配置、数据读取、PPI可视化及性能优化等核心环节,重点解决了版本兼容性、数据异常处理和中文乱码等实际问题,帮助用户高效处理雷达基数据并生成准确的PPI图像。

cc789的博客 1068

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

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

557

Hi3516CV610硬件设计避坑指南:从电源模块到DDR布线实战解析

本文深入解析了Hi3516CV610硬件设计中的关键难点与实战技巧。重点剖析了电源架构的选型陷阱与PCB布局要点,详细阐述了DDR3/L高速布线的等长匹配、信号完整性及端接策略,并提供了MIPI接口与时钟电路的隔离设计指南。旨在帮助工程师规避常见设计错误,提升系统稳定性与可靠性。

ooo22的博客 255

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

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

didiao11300的专栏 723

Ansys Zemax与Speos协同设计:HUD系统从光学优化到驾驶模拟的全流程解析

本文详细解析了如何利用Ansys Zemax与Speos这对“黄金搭档”进行HUD系统的协同设计。流程始于Zemax进行核心光学架构与像差优化,奠定性能基础;随后将设计无缝导入Speos,通过HUD光学分析模块进行量化验证;最终在虚拟驾驶环境中进行沉浸式模拟,评估实际视觉体验与系统集成效果,实现从光学优化到驾驶模拟的全流程闭环。

weixin_29201933的博客 273

EBOM转MBOM实战:华为云数字工厂如何5步搞定BOM自动转换(含避坑指南)

本文详细解析了华为云数字工厂平台如何通过五步自动化流程实现EBOM到MBOM的高效转换,涵盖模型预配置、逻辑流编排、工艺属性注入等关键步骤,并提供了多工厂差异化配置、历史数据迁移等典型场景的避坑指南。该方案显著提升转换效率,降低差错率,助力企业实现数字化转型。

weixin_29215391的博客 269

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

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

小威的博客 2万+

addr2line解析不出来行号的解决方式(汇编解析高阶版)

摘要:本文针对AEC crash问题中addr2line无法解析行号的情况,通过llvm-addr2line和反汇编分析,定位到CamX::AECBEStats17::AdjustROIParams函数中的乘法溢出问题。关键发现包括: 常规addr2line只能解析到函数名但无具体行号 llvm-addr2line解析出多个可能溢出点(行196/204/211/218/270/271) 反汇编显示6个条件分支跳转到溢出处理函数 源码分析确认这些位置均存在乘法运算 最终通过汇编级调试工具成功定位UBsan报告

168

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

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

RR1335 之代码才是动力源 260

【硬件的单元测试 UT 3】PCIe 3.0及信号完整性测试方法

PCIe标准自从推出以来,1代和2代标准已经在PC和Server上逐渐普及,用于满足高速显卡、高速存储设备对于高速数据传输的要求。出于支持更高总线数据吞吐率的目的,PCI-SIG组织在2010年制定了PCIe 3.0,即PCIe 3代的规范,数据速率达到8Gbps。

qq_43416206的博客 1414

Ardupilot二次开发(二):自定义mavlivk消息

在下面的文件添加自定义消息的xml定义然后编译固件,会生成相应的消息头文件。

超维空间科技的博客 2313

设计模式之迭代器模式

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

倪先生的博客 129

Could not find a package configuration file provided by “boost_signals“

gmapping/slam_gmapping/gmapping/CMakeLists.txt:14 (find_package)问题在14行,注释该行。,该语句的用以为告诉项目Boost库文件所在。

weixin_72050316的博客 1027

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

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

YoseZang的博客 809

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

scorpio的博客 503

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

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

kaven 1643

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、付费专栏及课程。

余额充值