首页 / Java 入门教程 / 数组遍历

Java 入门教程

数组遍历

本教程共 100 篇 · 第 25 篇 · 更新于 2026-08-05 · 约 6 分钟阅读

JavaJava 入门教程数组遍历求和求最大值

本节目标:掌握用下标 for 和增强 for 两种方式把数组每个元素走一遍,并能顺手写出求最大值、求和、求平均这些经典算法。

把数组建好,下一步多半是”把里面的数挨个看一遍”。这叫遍历。两种主流写法:下标 for 和增强 for。遍历是所有数组算法的地基,求最值、求和、统计都建立在它之上。

下标 for 遍历

知道长度,用下标一个一个取:

int[] scores = {88, 92, 75, 60};
for (int i = 0; i < scores.length; i++) {
    System.out.println("第" + i + "个:" + scores[i]);
}

i < scores.length 是铁律,确保不越界。下标遍历的好处是你知道”当前是第几个”,想改值也行。length 是数组自带的属性,不用你自己数,这也是用 length 而不是硬编码数字的原因。

Note

scores.length 是属性,不是方法,所以不带括号。Stringlength() 是方法,别搞混了。

增强 for 遍历

只读不写时,增强 for 更清爽:

for (int s : scores) {
    System.out.println(s);
}

不用管下标、不怕越界。缺点是没有下标,也不知道总共有几个(虽然可以另外数)。当你只关心”每个元素是什么”而不关心”排第几”时,它是最舒服的写法。

Tip

遍历只是”看”,用增强 for;遍历中要改元素或要下标,用下标 for。这一条在数组和集合里都通用,记住能少写很多 bug。

求总和与平均值

int sum = 0;
for (int s : scores) {
    sum += s;
}
double avg = (double) sum / scores.length;
System.out.println("总和:" + sum + ",平均:" + avg);

注意求平均时把 sum 强转成 double,否则整数相除会丢掉小数。这是新手常踩的坑:两个整数相除结果还是整数,1/2 得 0 而不是 0.5。

Warning

整数相除丢小数是高频错误。只要想保留小数,除数或被除数至少一个强转成 double。比如 (double) sum / lensum / (double) len

求最大值

思路:先假设第一个最大,然后逐个比,遇到更大的就更新。

int max = scores[0];              // 假设第一个最大
for (int i = 1; i < scores.length; i++) {
    if (scores[i] > max) {
        max = scores[i];          // 碰到更大的就替换
    }
}
System.out.println("最大值:" + max);

从下标 1 开始比,因为 scores[0] 已经当成初值了。这种”先设擂主、逐个挑战”的模式在算法里叫擂台法,非常经典。

Warning

求最大值别用 int max = 0 当初值——万一把所有数都是负数,0 反而最大,结果就错了。正确做法是用数组里真实存在的元素(如 scores[0])当起点。

求最小值

和求最大值对称,反过来比就行:

int min = scores[0];
for (int i = 1; i < scores.length; i++) {
    if (scores[i] < min) {
        min = scores[i];
    }
}
System.out.println("最小值:" + min);

同理,最小值初值也别硬编码一个很大的数,从数组取第一个元素当起点最稳。

统计满足条件的个数

int count = 0;
for (int s : scores) {
    if (s >= 60) {
        count++;          // 及格的记一个
    }
}
System.out.println("及格人数:" + count);

这种”设计数器、满足条件就加一”的模式非常常见,记住它。以后过滤集合、统计日志,底层都是这套思路:遍历一遍,符合条件的就累加。

遍历中不要改数组长度

遍历数组时往里加元素或删元素,会ConcurrentModificationException。Java 的数组是定长的,不能增删,只能改值。想增删,用后面学的集合类。

// 错的示范:遍历里不能改数组长度
for (int s : scores) {
    // 没有任何 API 能在这里加/删元素
}

增强 for 的值是副本

增强 for 里拿到的变量是数组元素的副本,改它不影响原数组。

int[] nums = {1, 2, 3};
for (int n : nums) {
    n = n * 2;          // 改的是副本,不是数组里真正的元素
}
System.out.println(nums[0]);    // 还是 1,没变

想改数组里的值,必须用下标 for,通过 nums[i] 直接操作。

Note

增强 for 的”副本”机制对基本类型是直接复制值。对引用类型,复制的是引用(地址),所以修改对象的属性会真的改掉对象本身:

class Student {
    String name;
    Student(String name) { this.name = name; }
}

Student[] students = {new Student("Tom"), new Student("Jerry")};
for (Student s : students) {
    s.name = "改了";    // 改的是对象属性,不是副本引用,所以会影响原数组
}
System.out.println(students[0].name);   // 改了

小心空数组和空引用

下标遍历前先确认数组不是 null,且长度大于 0,否则可能抛异常。

Note

遍历空数组(length 为 0)循环体一次都不跑,是安全的。但数组变量本身是 null 时访问 .length 会抛 NullPointerException。区分”空数组”和”空引用”:前者有对象只是没元素,后者连对象都没有。

int[] empty = new int[0];
System.out.println(empty.length);   // 0,安全

int[] nullArr = null;
System.out.println(nullArr.length); // NullPointerException!

Java 25 LTS 与老写法对照

遍历语法在 Java 25 LTS 没有变化。但老代码里还能看到这些面孔:

写法状态说明
for (int i=0; i<arr.length; i++)✅ 标准下标遍历
for (int x : arr)✅ 标准增强 for,Java 5+
for (int i=0; i<=arr.length-1; i++)⚠️ 啰嗦能跑,但没必要
while (i < arr.length) 手写⚠️ 啰嗦for 已经够用

Java 21 引入了 Stream API 的增强,也可以遍历数组:

import java.util.Arrays;

int[] scores = {88, 92, 75, 60};
Arrays.stream(scores).forEach(System.out::println);

这是函数式风格,初学了解就行,后面学 Stream 时会细讲。

遍历的性能对比

下标 for 和增强 for 在性能上几乎没差别。增强 for 编译后就是下标 for 的语法糖,JVM 优化后一模一样。不用纠结用哪个更快,按”要不要改值、要不要下标”来选就行。

真正影响性能的是遍历内部的逻辑:

// 差的写法:每次循环都调 length
for (int i = 0; i < scores.length; i++) { ... }

// 好的写法:length 提到循环外
int len = scores.length;
for (int i = 0; i < len; i++) { ... }

现代 JVM 对 scores.length 有内联优化,实际差别微乎其微。但”先存 length”在超大规模循环(百万次以上)里确实能省一点。

数组反转算法

反转是遍历的经典应用——首尾对称交换:

int[] arr = {1, 2, 3, 4, 5};
for (int i = 0; i < arr.length / 2; i++) {
    int temp = arr[i];
    arr[i] = arr[arr.length - 1 - i];
    arr[arr.length - 1 - i] = temp;
}
System.out.println(Arrays.toString(arr));   // [5, 4, 3, 2, 1]

只遍历前半部分,和后半部分交换。注意只跑到 length / 2,否则交换两次等于没换。

速查表

写法适用场景能改元素能取下标
下标 for要改值、要下标
增强 for只读遍历
典型算法核心思路
求和/平均累加,平均注意强转 double
求最值初值用第一个元素,擂台法比较
计数满足条件就 count++
查找遍历匹配,找到可 break
过滤把符合条件的收集到新数组
反转首尾对称交换,只跑一半

常见疑问

Q:增强 for 能 break 提前退出吗? 能。breakcontinue 在两种 for 里都一样用。找到目标就可以 break,不用傻傻跑完。

Q:数组遍历用 i <= length - 1 可以吗? 能跑,但没人这么写。i < length 更简洁直观。别给自己找麻烦。

Q:二维数组怎么遍历? 外层 for 走行,内层 for 走列。下节会详细讲。

Q:遍历数组时能删元素吗? 数组是定长的,没有删元素的方法。想”删”只能把后面的元素往前挪,或者用 ArrayList 的 remove

Q:遍历和迭代有什么区别? 在 Java 语境里,“遍历”和”迭代”基本同义。严格来说,迭代(iteration)更强调”用迭代器(Iterator)遍历集合”,而遍历(traversal)更通用。数组只能用 for 遍历,集合既可以用 for,也可以用迭代器。