【Java基础】Java集合遍历方式

news2025/4/19 7:05:00

前言

在Java编程中,集合(Collection)是存储和操作对象的核心工具。遍历集合是开发者最频繁的操作之一,但不同场景下选择合适的遍历方式至关重要。

一、基础遍历方式

1. 基本for循环

适用场景:仅适用于List等有序集合(如ArrayListLinkedList)。
核心思路:通过索引直接访问元素。
特点

  • 优点:索引操作灵活,适合需频繁访问索引的场景(如修改元素位置)。
  • 缺点:代码冗余,无法遍历SetMap;遍历中修改集合会抛出ConcurrentModificationException异常。
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (int i = 0; i < list.size(); i++) {
    System.out.println("索引 " + i + ": " + list.get(i));
}

2. 增强for循环(for-each

适用场景:所有实现Iterable接口的集合(如ListSetMap.entrySet())。
核心思路:隐式迭代器,无需显式管理索引。
特点

  • 优点:语法简洁,可读性强;无需处理索引或迭代器。
  • 缺点:无法在遍历中修改集合(添加/删除元素会抛出异常);无法获取元素索引。
List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {
    System.out.println("元素: " + item);
}

二、进阶遍历方式

3. Iterator迭代器

适用场景:所有集合类型(ListSetMap)。
核心思路:通过迭代器逐个访问元素,支持安全删除。
特点

  • 优点:支持遍历中安全删除元素iterator.remove());兼容所有集合类型。
  • 缺点:代码复杂度较高;无法直接添加元素或获取索引。
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println("当前元素: " + item);
    if (item.equals("B")) {
        iterator.remove(); // 安全删除元素
    }
}

4. ListIterator(双向遍历)

适用场景:仅适用于List接口的实现类。
核心思路:支持正向/反向遍历,可获取当前索引并插入元素。
特点

  • 优点:双向遍历(next()/previous());支持索引操作和插入。
  • 缺点:实现复杂,适用场景有限。
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
ListIterator<String> iterator = list.listIterator();
// 正向遍历
System.out.println("正向遍历:");
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
// 反向遍历
System.out.println("反向遍历:");
while (iterator.hasPrevious()) {
    System.out.println(iterator.previous());
}

三、函数式与并行遍历

5. Stream API(Java 8+)

适用场景:复杂操作(过滤、映射、并行处理)。
核心思路:函数式编程范式,支持链式调用。
特点

  • 优点:支持filtermapreduce等高阶操作;可并行处理(parallel())。
  • 缺点:性能开销较高;不支持直接修改集合。
List<String> list = Arrays.asList("A", "B", "C");
// 简单遍历
list.stream().forEach(System.out::println);
// 过滤后遍历
list.stream()
    .filter(s -> s.length() > 1)
    .map(String::toUpperCase)
    .forEach(System.out::println);

6. forEach方法(Java 8+)

适用场景:所有集合类型,结合Lambda表达式使用。
核心思路:基于Collection.forEach(Consumer)接口。
特点

  • 优点:语法简洁,与Lambda结合自然。
  • 缺点:本质是Iterator,无法在遍历中修改集合。
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
list.forEach(item -> {
    if (item.equals("B")) {
        System.out.println("找到元素B");
    }
});

四、对比与选择建议

对比表格

方法适用集合类型支持索引支持删除代码简洁性适用场景
基本forList需要索引操作的场景
增强for所有Iterable简单遍历,无需修改集合
Iterator所有集合安全删除元素的场景
ListIteratorList双向遍历或插入元素
Stream API所有集合高(函数式)复杂操作(过滤、映射、并行)
forEach所有集合简单遍历,结合Lambda表达式

选择建议

  1. 简单遍历:优先使用增强for循环forEach
  2. 需要删除元素:使用**Iterator**(避免ConcurrentModificationException)。
  3. 双向遍历或插入:使用**ListIterator**。
  4. 复杂操作(过滤、并行):使用**Stream API**。
  5. 索引操作:使用基本for循环ListIterator

五、注意事项

1. ConcurrentModificationException的根源

  • 原因:在遍历过程中直接修改集合(如通过remove()add())会破坏迭代器的内部状态。
  • 解决方案
    • 使用Iterator.remove()安全删除元素。
    • 遍历前创建临时集合存储需删除的元素,遍历后统一处理。

2. 并行遍历的性能考量

  • Stream.parallel():适合大数据量场景,但需注意线程安全与任务分割开销。

六、总结

Java集合遍历方式的选择需结合具体场景,从可读性安全性性能等维度综合评估。掌握每种方法的核心特性,能显著提升代码质量和开发效率。无论是基础循环还是函数式编程,理解其底层原理(如迭代器机制、流处理)是进阶的关键。


延伸阅读

  • Fail-Fast机制与ConcurrentModificationException的深层原理。
  • Stream的惰性求值与中间操作/终端操作的区别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rust-引用借用规则

目录 一、概述 二、借用规则 三、详细解释 3.1 第一条规则 3.2 第二条规则 3.3 第三条规则 四、总结 Welcome to Code Blocks blog 本篇文章主要介绍了 [Rust-引用借用规则] ❤博主广交技术好友&#xff0c;喜欢文章的可以关注一下❤ 一、概述 Rust为确保程序在运行时不…

如何保障企业数据的安全?软件开发中的数据安全防护措施

引言 随着数字化转型的推进&#xff0c;数据已经成为企业最重要的资产之一。然而&#xff0c;随着数据量的增长&#xff0c;数据泄露、丢失和滥用的风险也不断增加。如何保障企业数据的安全&#xff0c;成为企业在进行软件开发时必须重点关注的问题。本文将介绍软件开发中的一些…

Linux安装开源版MQTT Broker——EMQX服务器环境从零到一的详细搭建教程

零、EMQX各个版本的区别 EMQX各个版本的功能对比详情https://docs.emqx.com/zh/emqx/latest/getting-started/feature-comparison.html

【软件工程大系】净室软件工程

净室软件工程&#xff08;Cleanroom Software Engineering&#xff09;是一种以缺陷预防&#xff08;正确性验证&#xff09;为核心的软件开发方法&#xff0c;旨在通过严格的工程规范和数学验证&#xff0c;在开发过程中避免缺陷的产生&#xff0c;而非依赖后期的测试和调试。…

软考 系统架构设计师系列知识点之杂项集萃(49)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;48&#xff09; 第76题 某文件管理系统在磁盘上建立了位视图&#xff08;bitmap&#xff09;&#xff0c;记录磁盘的使用情况。若磁盘上物理块的编号依次为&#xff1a;0、1、2、……&#xff1b…

JVM 调优不再难:AI 工具自动生成内存优化方案

在 Java 应用程序的开发与运行过程中&#xff0c;Java 虚拟机&#xff08;JVM&#xff09;的性能调优一直是一项极具挑战性的任务&#xff0c;尤其是内存优化方面。不合适的 JVM 内存配置可能会导致应用程序出现性能瓶颈&#xff0c;甚至频繁抛出内存溢出异常&#xff0c;影响业…

封装Tcp Socket

封装Tcp Socket 0. 前言1. Socket.hpp2. 简单的使用介绍 0. 前言 本文中用到的Log.hpp在笔者的历史文章中都有涉及&#xff0c;这里就不再粘贴源码了&#xff0c;学习地址如下&#xff1a;https://blog.csdn.net/weixin_73870552/article/details/145434855?spm1001.2014.3001…

Linux 入门九:Linux 进程间通信

概述 进程间通信&#xff08;IPC&#xff0c;Inter-Process Communication&#xff09;是指在不同进程之间传递数据和信息的机制。Linux 提供了多种 IPC 方式&#xff0c;包括管道、信号、信号量、消息队列、共享内存和套接字等。 方式 一、管道&#xff08;Pipe&#xff09…

Redis之缓存更新策略

缓存更新策略 文章目录 缓存更新策略一、策略对比二、常见的缓存更新策略三、如何选择策略四、实际应用示例五、使用 Cache-Aside TTL 的方式&#xff0c;实现缓存商铺信息详情1.引入StringRedisTemplate2.将查询商铺信息加入缓存3.更新商铺信息时移除缓存总结 六、注意事项 一…

【leetcode100】杨辉三角

1、题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]…

Selenium2+Python自动化:利用JS解决click失效问题

文章目录 前言一、遇到的问题二、点击父元素问题分析解决办法实现思路 三、使用JS直接点击四、参考代码 前言 在使用Selenium2和Python进行自动化测试时&#xff0c;我们有时会遇到这样的情况&#xff1a;元素明明已经被成功定位&#xff0c;代码运行也没有报错&#xff0c;但…

OpenStack Yoga版安装笔记(十九)启动一个实例(Self-service networks)

1、概述 1.1 官方文档 Launch an instancehttps://docs.openstack.org/install-guide/launch-instance.html 《OpenStack Yoga版安装笔记&#xff08;十四&#xff09;启动一个实例》文档中&#xff0c;已经按照Option1: Provider networks创建网络。 本文按照Option2&#…

数学教学通讯杂志数学教学通讯杂志社数学教学通讯编辑部2025年第6期目录

课程教材教法 “课程思政”视域下的高中数学教学探索与实践——以“函数概念的发展历程”为例 赵文博; 3-617 PBL教学模式下高中统计教学的探索与实践——以“随机抽样&#xff08;第一课时&#xff09;”为例 陈沛余; 7-10 “三新”背景下的高中数学教学困境与应对…

C#容器源码分析 --- Dictionary<TKey,TValue>

Dictionary<TKey, TValue> 是 System.Collections.Generic 命名空间下的高性能键值对集合&#xff0c;其核心实现基于​​哈希表​​和​​链地址法&#xff08;Separate Chaining&#xff09;。 .Net4.8 Dictionary<TKey,TValue>源码地址&#xff1a; dictionary…

在 Visual Studio Code 中安装通义灵码 - 智能编码助手

高效的编码工具对于提升开发效率和代码质量至关重要。 通义灵码作为一款智能编码助手&#xff0c;为开发者提供了全方位的支持。 本文将详细介绍如何在 Visual Studio Code&#xff08;简称 VSCode&#xff09;中安装通义灵码&#xff0c;以及如何进行相关配置以开启智能编码…

idea报错java: 非法字符: ‘\ufeff‘解决方案

解决方案步骤以及说明 BOM是什么&#xff1f;1. BOM的作用2. 为什么会出现 \ufeff 错误&#xff1f;3. 如何解决 \ufeff 问题&#xff1f; 最后重新编译&#xff0c;即可运行&#xff01;&#xff01;&#xff01; BOM是什么&#xff1f; \ufeff 是 Unicode 中的 BOM&#xff0…

PHY芯片与网络变压器接线设计指南——不同速率与接口的硬件设计原则

一、PHY与网络变压器的核心作用 • PHY芯片&#xff08;物理层芯片&#xff09; • 功能&#xff1a;实现数据编码&#xff08;如Manchester、PAM4&#xff09;、时钟恢复、链路协商&#xff08;Auto-Negotiation&#xff09;。 • 接口类型&#xff1a;MII/RMII/GMII/RGMII/…

【学习笔记】计算机网络(八)—— 音频/视频服务

第8章 互联网上的音频/视频服务 文章目录 第8章 互联网上的音频/视频服务8.1概述8.2 流式存储音频/视频8.2.1 具有元文件的万维网服务器8.2.2 媒体服务器8.2.3 实时流式协议 RTSP 8.3 交互式音频/视频8.3.1 IP 电话概述8.3.2 IP电话所需要的几种应用协议8.3.3 实时运输协议 RTP…

linux: 文件描述符fd

目录 1.C语言文件操作复习 2.底层的系统调用接口 3.文件描述符的分配规则 4.重定向 1.C语言文件操作复习 文件 内容 属性。所有对文件的操作有两部分&#xff1a;a.对内容的操作&#xff1b;b.对属性的操作。内容是数据&#xff0c;属性其实也是数据-存储文件&#xff0c…

记录一次后台项目的打包优化

文章目录 前言分析问题寻找切入点根据切入点逐一尝试cdn引入node包遇到的一些问题记录最终结果 前言 优化&#xff0c;所有开发者到一定的程度上&#xff0c;都绕不开的问题之一 例如&#xff1a; 首页加载优化白屏优化列表无限加载滚动优化&#xff0c;图片加载优化逻辑耦合…