Java纯数组遍历需兼顾可读性、安全性和效率:传统for循环控制力强、性能优,适合需索引的场景;增强for循环简洁安全但无法获取索引;Arrays.stream()函数式编程灵活但有开销。

Java 数组遍历本身不复杂,但选对方式能兼顾可读性、安全性与执行效率。原生数组(int[]、String[] 等)和集合(如 ArrayList)的遍历机制不同,不能一概而论——这里聚焦**纯数组**(非集合),讲清最常用、最实用的几种写法及其真实影响。
传统 for 循环:控制力最强,适合需要索引的场景
直接通过下标访问,语义清晰,JVM 优化成熟,是性能基准线。
例如:
int[] arr = {10, 20, 30, 40};
for (int i = 0; i < arr.length; i++) {
System.out.println("索引 " + i + ": " + arr[i]);
}
关键点:
立即学习“Java免费学习笔记(深入)”;
-
避免重复调用
arr.length:虽然现代 JVM 多数会自动内联优化,但显式缓存仍更稳妥,尤其在高频循环中:for (int i = 0, len = arr.length; i - 支持正向/反向遍历、步长跳变(如
i += 2)、边界条件判断(如只处理前半部分) - 唯一能自然获取当前元素索引的方式,适用于查找、替换、构建新数组等操作
增强 for 循环(for-each):代码最简洁,适合只读遍历
语法糖,底层编译后仍转为基于索引的访问(对数组而言),不是迭代器。
例如:
for (int num : arr) {
System.out.println(num);
}
优点明显:
- 无索引变量干扰,意图明确:“只关心每个值”
- 不易越界,杜绝
ArrayIndexOutOfBoundsException风险 - 编译后性能与传统 for 几乎一致,实测差异通常在纳秒级,可忽略
限制也很清楚:
- 无法获取当前索引(除非额外声明计数器)
- 不能修改原数组引用(如
num = 100只改副本,不影响arr[i]) - 不支持中途跳出多层循环(需靠标签或提取方法)
Stream API:声明式表达,但开销不可忽视
适合数据转换、过滤、聚合等函数式操作,**不推荐仅用于简单遍历**。
例如:
Arrays.stream(arr).forEach(System.out::println);
真实成本包括:
- 创建 Stream 对象、包装 IntStream、触发终端操作的内部链路
- 装箱开销(如
int[]→IntStream→ 自动拆箱再消费) - 实测百万级数组遍历,Stream 比传统 for 慢 3–5 倍,且 GC 压力略高
建议仅在满足以下任一条件时使用:
- 需要链式操作(如
filter().map().sum()) - 配合并行流处理超大数组(
parallelStream(),注意线程安全) - 团队统一风格,且性能非关键路径
性能小结:别过早优化,但要懂取舍
对普通业务数组(几千到几十万元素),三种方式实际耗时差距微乎其微。真正影响性能的往往是循环体内的操作(如 IO、复杂计算、对象创建),而非遍历结构本身。
所以优先级建议:
- 只读且无需索引 → 用增强 for(清晰、安全、够快)
- 需索引、需修改、需精细控制 → 用传统 for(可靠、灵活、无歧义)
- 要做过滤/映射/归约 → 再考虑 Stream(功能优先,接受合理开销)
- 绝对性能敏感(如游戏引擎、高频交易)→ 固定长度+传统 for+手动展开(极端情况)
记住:数组遍历的“效率”不仅看执行时间,还包括可维护性、出错率和后续扩展成本。



















