当前位置: 首页 > news >正文

java的迭代器

iterable接口

内部通过iterator()方法返回一直iterator实例,iterator才是实际执行遍历操作的对象

所有实现iterator的类都可以使用增强for循环,底层实际上是获取iteraior进行遍历

iterator接口

boolean hasNext(); // 是否还有下一个元素
E next();          // 获取下一个元素
void remove();     // 移除当前元素(可选)

支持边遍历边修改

遍历是单向的

例如ArrayList和LinkedList的hasNext的底层原理都是维护一个游标cursor表示当前位置,来与列表大小进行比较

ListIterator接口

list的双向迭代器

public interface ListIterator<E> extends Iterator<E> {boolean hasPrevious();E previous();int nextIndex();int previousIndex();void set(E e); // 替换当前元素void add(E e); // 添加新元素
}

Spliterator接口

public interface Spliterator<T> {boolean tryAdvance(Consumer<? super T> action);Spliterator<T> trySplit(); // 拆分long estimateSize();       // 估计剩余数量int characteristics();     // 特性标志位
}List<String> list = Arrays.asList("A", "B", "C", "D", "E");
Spliterator<String> spliterator = list.spliterator();Spliterator<String> part1 = spliterator.trySplit();
if (part1 != null) {part1.forEachRemaining(System.out::println); // 处理前半部分
}
spliterator.forEachRemaining(System.out::println); // 处理后半部分

迭代器行为机制

fail-fast

当检测到在迭代过程中发生了结构性的改变(添加、删除元素),迭代器会立即抛出ConcurrentModificationException异常

这种机制依赖一个计数器来跟踪集合结构的变化,如果在迭代期间发现这个计数器与预期不符,就会认为这个集合被并发修改了,立即抛出异常

大多数标准的java集合类默认使用的都是fail-fast

例如在遍历arraylistist通过list.add()或者list.remove()修改列表,同时又使用迭代器遍历,就会抛出异常

这是因为arraylist内部使用一个modCount的字段记录集合被修改的次数,迭代器内部也维护了一个对modCount的引用,每次next()或hasNext()都会检查当前这个modCount和迭代器创建时的expectedModeCount是否相等,不想等就抛出异常【所以抛出异常的时机是迭代器执行next()或hasNext()的时候,不是修改集合的时候】

使用迭代器提供的remove()方法的话,不仅移除集合中元素,还会同步更新迭代器内的expectedModeCount,因此不会触发异常

fail-safe

即使集合在迭代过程中被修改了,也不会抛出异常,因为他们工作在一个集合的快照上,

迭代器访问的是集合的一个副本或视图,因此对原始集合的任何修改都不会影响正在进行中的迭代过程

但是看到的可能是过期的数据,因为反应的是迭代开始时刻的数据

CopyOnWriteArrayList、ConcurrentHashMap提供的就是fail-safe

http://www.lqws.cn/news/128161.html

相关文章:

  • 【推荐算法】推荐系统核心算法深度解析:协同过滤 Collaborative Filtering
  • 如何在 HTML 中添加按钮
  • 《复制粘贴的奇迹:原型模式》
  • Devops自动化运维---py基础篇一
  • TypeScript 编译 ES6+ 语法到兼容的 JavaScript介绍
  • C++性能优化指南
  • vue源码解析——diff算法
  • OpenCV C++ 心形雨动画
  • 多分辨率 LCD 的 GUI 架构设计与实现
  • 【从零学习JVM|第二篇】字节码文件
  • 深入解析 Java ClassLoader:揭开 JVM 动态加载的神秘面纱
  • Openlayers从入门到入坟
  • nmcli connection常用命令及设置wifi为AP模式
  • 第N1周:one-hot编码案例
  • 若依Ruoyi中优先从本地文件加载静态资源
  • constexpr 是 C++11 引入的关键字
  • Elasticsearch 集群运维常用命令详解
  • IDEA集成JRebel插件,实现实时热部署
  • vue2 项目中 npm run dev 运行98% after emitting CopyPlugin 卡死
  • Windows系统下npm报错node-gyp configure got “gyp ERR“解决方法
  • 【从0-1的HTML】第3篇:html引入css的3种方式
  • 通过ca证书的方式设置允许远程访问Docker服务
  • C++ 中的 const 知识点详解,c++和c语言区别
  • HTMLCSS 学习总结
  • Server - 使用 Docker 配置 PyTorch 研发环境
  • 【RAG优化】rag整体优化建议
  • Git的使用技巧
  • Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测
  • STM32的ADC简介
  • STM32----IAP远程升级