目录
- 前言
- [一、先懂索引:数组收纳盒的 "格子编号"](#一、先懂索引:数组收纳盒的 “格子编号”)
-
- [1.1 索引的核心概念](#1.1 索引的核心概念)
- [1.2 生活化类比](#1.2 生活化类比)
- [1.3 索引范围验证(代码示例)](#1.3 索引范围验证(代码示例))
- 二、单个元素的访问:存取指定格子的东西
-
- [2.1 取值语法:数组名 [索引]](#2.1 取值语法:数组名 [索引])
- [2.2 赋值语法:数组名 [索引] = 对应类型的值](#2.2 赋值语法:数组名 [索引] = 对应类型的值)
- [2.3 完整代码示例(存取操作)](#2.3 完整代码示例(存取操作))
- 三、数组遍历:把所有格子的东西过一遍
-
- [3.1 方式 1:普通 for 循环(万能遍历,可改元素)](#3.1 方式 1:普通 for 循环(万能遍历,可改元素))
- [3.2 方式 2:增强 for 循环(foreach,只读遍历,代码简洁)](#3.2 方式 2:增强 for 循环(foreach,只读遍历,代码简洁))
- [3.3 两种遍历方式对比(新手选对不踩坑)](#3.3 两种遍历方式对比(新手选对不踩坑))
- 四、高频坑:数组索引越界异常(ArrayIndexOutOfBoundsException)
-
- [4.1 异常原因(核心)](#4.1 异常原因(核心))
- [4.2 错误示例(运行时报错)](#4.2 错误示例(运行时报错))
- [4.3 规避方法(新手必记)](#4.3 规避方法(新手必记))
- [五、新手必避的 4 个 "遍历 / 访问致命坑"](#五、新手必避的 4 个 “遍历 / 访问致命坑”)
-
- [5.1 坑 1:增强 for 循环试图修改原数组](#5.1 坑 1:增强 for 循环试图修改原数组)
- [5.2 坑 2:循环条件用`i <= scores.length`](#5.2 坑 2:循环条件用
i <= scores.length) - [5.3 坑 3:索引从 1 开始(新手最易错)](#5.3 坑 3:索引从 1 开始(新手最易错))
- [5.4 坑 4:访问空数组 / 未初始化数组的索引](#5.4 坑 4:访问空数组 / 未初始化数组的索引)
- 总结
前言
上一节咱们搞定了数组的定义和初始化 ------ 造好了装数据的 "收纳盒",也给盒子装了默认值或自定义值。但光造好盒子没用,实际编程中得知道:怎么从指定格子里拿数据(取值)、怎么往指定格子里放新数据(赋值),以及怎么把所有格子的内容快速看一遍(遍历)。
新手最容易踩的坑就是 "找错格子编号"(索引越界),导致程序崩溃;还有人分不清 "普通 for 循环" 和 "增强 for 循环" 的用法,想改元素却用了只读的 foreach。这一节咱们就用 "收纳盒存取东西" 的类比,把数组访问、遍历的规则讲透,避开索引越界的坑,让新手能精准操作数组里的每一个元素!
一、先懂索引:数组收纳盒的 "格子编号"
想要访问数组元素,首先得认对 "格子编号"------ 也就是数组的索引(下标),这是操作数组的基础,新手必须记死核心规则。
1.1 索引的核心概念
数组的索引是给每个元素分配的唯一编号,作用是定位元素的位置,核心规则:
-
索引从0 开始,不是从 1!
-
索引的范围是:
0 ≤ 索引 < 数组长度(最大索引 = 数组长度 - 1); -
每个索引对应唯一一个元素,反之亦然。
1.2 生活化类比
一个长度为 5 的数组(5 个格子的收纳盒):

核心提醒:新手最容易把第 1 个元素的索引写成 1,这是高频错。
1.3 索引范围验证(代码示例)
java
public class ArrayIndex {
public static void main(String[] args) {
// 静态初始化:长度为3的数组,索引0/1/2
int[] scores = {90, 85, 95};
System.out.println("数组长度:" + scores.length); // 输出3
System.out.println("最大索引:" + (scores.length - 1)); // 输出2
}
}
二、单个元素的访问:存取指定格子的东西
知道了索引,就能精准操作单个元素 ------取值 (从格子里拿东西)和赋值(往格子里放东西),语法简单且固定。
2.1 取值语法:数组名 [索引]
直接通过 "数组名 + 索引" 获取对应位置的元素值,相当于 "打开指定格子拿东西"。
2.2 赋值语法:数组名 [索引] = 对应类型的值
给指定索引的元素赋新值,相当于 "把新东西放进指定格子,替换原来的内容"。
2.3 完整代码示例(存取操作)
java
public class ArrayAccess {
public static void main(String[] args) {
// 动态初始化:长度为3的int数组,默认值都是0
int[] scores = new int[3];
// 1. 赋值:往指定格子放数据
scores[0] = 90; // 第1个格子(索引0)放90
scores[1] = 85; // 第2个格子(索引1)放85
scores[2] = 95; // 第3个格子(索引2)放95
// 2. 取值:从指定格子拿数据
System.out.println("第1个学生成绩:" + scores[0]); // 输出90
System.out.println("第2个学生成绩:" + scores[1]); // 输出85
// 3. 重新赋值:替换格子里的内容
scores[1] = 92; // 把第2个格子的85改成92
System.out.println("修改后第2个学生成绩:" + scores[1]); // 输出92
}
}
关键提醒:赋值类型必须匹配
java
// 错误示例:int数组装字符串,编译报错
scores[0] = "90"; // 提示:String无法转换为int
三、数组遍历:把所有格子的东西过一遍
遍历就是 "逐个访问数组的所有元素",Java 里有两种常用方式,新手要根据场景选对:
3.1 方式 1:普通 for 循环(万能遍历,可改元素)
适用场景
-
需要用到索引的场景(比如按位置修改元素、统计某个位置的元素);
-
想要修改数组元素的场景;
-
最灵活,新手优先掌握。
语法格式
java
for (int i = 0; i < 数组名.length; i++) {
// i是索引,从0到数组长度-1
// 取值:数组名[i]
// 赋值:数组名[i] = 新值
}
代码示例(遍历 + 修改元素)
java
public class ArrayForLoop {
public static void main(String[] args) {
int[] scores = {90, 85, 95};
// 1. 遍历取值:打印所有成绩
System.out.println("遍历所有成绩:");
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i+1) + "个成绩:" + scores[i]);
}
// 2. 遍历修改:所有成绩加5分
System.out.println("\n成绩加5分后:");
for (int i = 0; i < scores.length; i++) {
scores[i] = scores[i] + 5; // 修改元素值
System.out.println("第" + (i+1) + "个成绩:" + scores[i]);
}
}
}
执行结果
java
遍历所有成绩:
第1个成绩:90
第2个成绩:85
第3个成绩:95
成绩加5分后:
第1个成绩:95
第2个成绩:90
第3个成绩:100
3.2 方式 2:增强 for 循环(foreach,只读遍历,代码简洁)
适用场景
-
仅需要读取元素值,不需要修改;
-
不需要用到索引的场景;
-
代码更简洁,少写索引相关的代码,降低出错概率。
语法格式
java
for (数据类型 变量名 : 数组名) {
// 变量名会依次接收数组的每个元素值(只读,无法修改原数组)
}
代码示例(仅遍历取值)
java
public class ArrayForeach {
public static void main(String[] args) {
int[] scores = {90, 85, 95};
// 增强for循环遍历:依次读取每个成绩
System.out.println("增强for循环遍历成绩:");
for (int score : scores) {
System.out.println(score); // 依次输出90、85、95
}
// 注意:增强for循环无法修改原数组元素
System.out.println("\n试图通过foreach修改成绩(无效):");
for (int score : scores) {
score = score + 5; // 只是修改临时变量score,原数组不变
System.out.println(score); // 输出95、90、100(临时值)
}
// 验证原数组:还是原来的值
System.out.println("\n原数组成绩:");
for (int score : scores) {
System.out.println(score); // 仍输出90、85、95
}
}
}
3.3 两种遍历方式对比(新手选对不踩坑)
| 遍历方式 | 能否用索引 | 能否修改原数组 | 代码简洁度 | 适用场景 |
|---|---|---|---|---|
| 普通 for 循环 | 能 | 能 | 稍繁琐 | 需要索引、修改元素、复杂遍历 |
| 增强 for 循环 | 不能 | 不能 | 很简洁 | 仅读取元素、简单遍历 |
四、高频坑:数组索引越界异常(ArrayIndexOutOfBoundsException)
这是新手操作数组时最常遇到的运行时异常,必须知道原因和规避方法。
4.1 异常原因(核心)
访问的索引超出了 "0 ~ 数组长度 - 1" 的范围,常见情况:
-
索引小于 0(比如
scores[-1]); -
索引大于等于数组长度(比如长度 3 的数组访问
scores[3]); -
循环条件写错(比如
i <= scores.length,应该是i < scores.length)。
4.2 错误示例(运行时报错)
java
public class ArrayIndexError {
public static void main(String[] args) {
int[] scores = {90, 85, 95}; // 长度3,索引0/1/2
// 错误1:索引等于长度(3)
System.out.println(scores[3]); // 运行时报错
// 错误2:循环条件用<=,导致i=3时访问scores[3]
for (int i = 0; i <= scores.length; i++) {
System.out.println(scores[i]); // 运行时报错
}
}
}
4.3 规避方法(新手必记)
-
牢记索引范围:
0 ≤ 索引 < 数组长度; -
循环遍历用
i < 数组名.length作为条件(而非<=); -
访问指定索引前,先检查索引是否在合法范围(比如用户输入索引时):
javaint index = 3; if (index >= 0 && index < scores.length) { System.out.println(scores[index]); } else { System.out.println("索引越界,合法范围是0~" + (scores.length-1)); }
五、新手必避的 4 个 "遍历 / 访问致命坑"
5.1 坑 1:增强 for 循环试图修改原数组
-
错误示例:
javafor (int score : scores) { score += 5; // 以为能改原数组,实际无效 } -
避坑:要修改数组用普通 for 循环,增强 for 循环只用来读取。
5.2 坑 2:循环条件用i <= scores.length
-
错误示例:
javafor (int i = 0; i <= scores.length; i++) { // i会到3,超出索引范围 System.out.println(scores[i]); } -
避坑:固定写
i < scores.length,从根源避免越界。
5.3 坑 3:索引从 1 开始(新手最易错)
-
错误示例:
java// 想访问第1个元素,却写索引1,实际拿到第2个元素 System.out.println("第1个成绩:" + scores[1]); -
避坑:记死 "第 n 个元素的索引是 n-1"。
5.4 坑 4:访问空数组 / 未初始化数组的索引
-
错误示例:
javaint[] scores = null; // 数组未初始化,指向null System.out.println(scores[0]); // 运行时报空指针异常 -
避坑:访问索引前,确保数组已初始化(不是 null)且长度 > 0。
总结
这一节咱们掌握了数组元素访问与遍历的核心技能,记住 3 个核心点:
-
索引规则:从 0 开始,范围是
0 ~ 数组长度-1,越界会抛出运行时异常; -
遍历选法:普通 for 循环可改元素、用索引,增强 for 循环仅只读、更简洁;
-
避坑核心:循环条件用
i < 数组长度,增强 for 循环不修改原数组,索引别从 1 开始。
数组的遍历是后续处理批量数据的基础(比如找最大值、排序),掌握好这两种遍历方式,后续学习数组操作会更轻松。