news 2026/6/9 23:33:06

集合的迭代器与遍历

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
集合的迭代器与遍历

Java集合迭代器与遍历:实现原理与性能优化

Java集合框架提供了多种迭代器和遍历方式,支持集合元素的顺序访问。为了深入理解集合的迭代和遍历过程,我们将从源码的角度详细分析迭代器的实现及其与遍历相关的操作。

1. 迭代器的基本概念

迭代器(Iterator)是用来遍历集合元素的对象,它提供了访问集合中元素的标准方式。通过迭代器,我们可以安全地从集合中提取元素,并且避免使用集合的索引或内部实现细节。Java中所有的集合类(如ListSet等)都可以通过Iterator接口提供迭代功能。

关键源码:Iterator接口

java复制

public interface Iterator<E> { boolean hasNext(); // 判断是否有下一个元素 E next(); // 获取下一个元素 void remove(); // 删除当前元素 }

2. 集合类中的迭代器实现

不同的集合类根据其内部数据结构,提供了不同的迭代器实现。以下是一些常见集合类的迭代器实现:

2.1ArrayList的迭代器实现

ArrayList使用数组作为底层数据结构,它的迭代器是通过内部类ArrayList$Itr实现的。

关键源码

java复制

public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // 当前游标位置 int lastRet = -1; // 上一次返回的元素索引 int expectedModCount = modCount; // 期望的修改次数 public boolean hasNext() { return cursor != size; } 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; lastRet = i; return (E) elementData[lastRet]; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }

2.2HashSet的迭代器实现

HashSet基于哈希表实现,其迭代器通过内部类HashSet$Iterator实现。与ArrayList类似,但哈希表的元素顺序是无序的。

关键源码

java复制

public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int expectedModCount; int nextIndex; Itr() { expectedModCount = modCount; nextIndex = 0; } public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); try { int i = nextIndex; E next = getEntry(i).element; nextIndex = i + 1; return next; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }

3. 迭代器的基本操作

Iterator接口中,主要有以下三个操作方法:

  • hasNext():判断是否有下一个元素。
  • next():获取下一个元素。
  • remove():删除当前元素。

通过这三个方法,用户可以遍历集合中的元素,并根据需要删除元素。例如,ArrayListItr内部类通过游标管理当前的元素位置,并支持元素的删除操作。

4. for-each循环与迭代器

Java中的增强for循环(即for-each循环)本质上是通过迭代器来实现的。每当我们使用for-each循环时,编译器会自动为我们创建一个Iterator对象,并调用Iteratornext()方法来逐一访问集合元素。

示例代码

java复制

for (E element : collection) { // 使用 element }
编译器转换

实际上,编译器会将上述代码转化为:

java复制

for (Iterator<E> it = collection.iterator(); it.hasNext(); ) { E element = it.next(); // 使用 element }

5. 迭代器的并发问题

在多线程环境中,迭代器可能面临并发问题。例如,在一个线程遍历集合时,另一个线程可能会修改集合的结构(增加、删除元素)。为了避免出现并发修改异常,Java集合框架提供了一些机制来处理并发情况。

关键源码:ConcurrentModificationException

当集合结构发生修改时,迭代器会检测到不一致,并抛出ConcurrentModificationException异常。以下是ArrayList中的modCount检测逻辑:

java复制

public final class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable { private transient int modCount = 0; // 记录集合修改次数 public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int expectedModCount = modCount; // 期望的modCount值 public E next() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); // 检测到结构修改 } // 其他逻辑 } } }

6. 集合的遍历方式

除了使用Iterator进行遍历外,Java提供了多种遍历集合的方式。常见的有:

  • 增强for循环:适用于所有实现了Iterable接口的集合类。
  • ListIteratorList接口提供了ListIterator,它不仅支持正向遍历,还支持反向遍历、修改元素等功能。

关键源码:ListIterator

java复制

public interface ListIterator<E> extends Iterator<E> { boolean hasPrevious(); // 判断是否有前一个元素 E previous(); // 获取前一个元素 void set(E e); // 设置当前元素 void add(E e); // 在当前元素前添加元素 }

7. 集合遍历的性能优化

在实际开发中,遍历集合时的性能也需要考虑。以下是一些优化建议:

  • ArrayList:使用Iterator遍历比直接使用索引访问更有效,因为每次访问索引都需要重新计算位置。
  • LinkedList:使用迭代器遍历的性能相对较好,因为它采用双向链表存储数据,可以更快地访问元素。
  • 大规模数据集合:避免在遍历过程中进行不必要的修改操作,并优先考虑使用高效的遍历方式,如并行流(parallelStream)来实现多线程遍历。

示例代码:并行流遍历

java复制

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); numbers.parallelStream().forEach(System.out::println);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 4:49:44

Sambert-HiFiGAN推理延迟高?批处理优化部署教程

Sambert-HiFiGAN推理延迟高&#xff1f;批处理优化部署教程 1. 为什么你的Sambert语音合成总在“卡顿”&#xff1f; 你是不是也遇到过这样的情况&#xff1a;点下“生成语音”按钮&#xff0c;界面转圈十几秒才出声&#xff1b;批量合成50条文案时&#xff0c;每条都要等3秒…

作者头像 李华
网站建设 2026/6/5 5:38:28

社区养老试点:24小时语音监护老人异常行为与情绪

社区养老试点&#xff1a;24小时语音监护老人异常行为与情绪 在社区养老服务中心&#xff0c;一位独居老人凌晨三点突然剧烈咳嗽&#xff0c;随后传来茶杯摔落声和长时间沉默——传统跌倒报警器未触发&#xff0c;而值班人员正熟睡。三分钟后&#xff0c;系统自动拨通家属电话…

作者头像 李华
网站建设 2026/6/9 18:14:10

fft npainting lama初始化卡住?模型加载问题排查

FFT NPainting LaMa初始化卡住&#xff1f;模型加载问题排查 1. 问题现象与背景说明 1.1 用户常遇到的“卡在初始化”场景 你是否也遇到过这样的情况&#xff1a; 执行 bash start_app.sh 后&#xff0c;终端停在这一行不动了&#xff1a; Initializing model...或者更隐蔽…

作者头像 李华
网站建设 2026/6/5 2:07:05

STM32奇偶校验与软件模拟对比分析:全面讲解

以下是对您提供的博文内容进行 深度润色与结构重构后的专业级技术文章 。整体风格更贴近一位资深嵌入式工程师在技术博客或内部分享会上的自然讲述——逻辑清晰、语言精炼、有实战温度&#xff0c;同时彻底去除AI生成痕迹&#xff08;如模板化句式、空洞总结、机械罗列&#…

作者头像 李华
网站建设 2026/6/5 10:37:36

Ubuntu 22.04服务器版libwebkit2gtk-4.1-0安装注意事项

以下是对您提供的博文内容进行 深度润色与结构重构后的技术文章 。整体遵循“去AI化、强工程感、重实操性、语言自然流畅”的原则,摒弃模板化标题和刻板逻辑链,以一位资深嵌入式/Linux系统工程师第一视角展开叙述,融合真实调试经验、踩坑复盘与架构思考,同时严格保留所有…

作者头像 李华
网站建设 2026/6/9 18:33:07

Qwen-Image-2512值得部署吗?真实出图效果与效率测评

Qwen-Image-2512值得部署吗&#xff1f;真实出图效果与效率测评 你是不是也刷到过那些让人眼前一亮的AI生成图——光影细腻、构图自然、细节丰富&#xff0c;甚至带点电影感&#xff1f;最近不少朋友在问&#xff1a;阿里新推的Qwen-Image-2512&#xff0c;真有那么强&#xf…

作者头像 李华