数组
概述
数组(Array)是同一类型元素的固定长度、连续存储的容器。数组中每个元素通过索引(从 0 开始)访问,长度在创建时确定且不可改变。掌握数组是理解 集合 和循环遍历的基础。
本文介绍:数组的声明与创建、访问与长度、遍历方式、默认值、多维数组,以及常见陷阱与最佳实践。
声明与创建
基本语法
数组的声明有两种常见写法;创建时必须指定长度或直接给出元素列表。
// 写法一:类型[] 变量名(推荐,类型与[] 结合更清晰)
int[] arr1;
String[] names;
// 写法二:类型 变量名[](合法但不如写法一常用)
int arr2[];
// 创建:new 元素类型[长度]
arr1 = new int[5]; // 长度为 5 的 int 数组
names = new String[3]; // 长度为 3 的 String 数组
// 声明并创建可写在一行
double[] scores = new double[10];直接初始化(创建时给出所有元素,长度由元素个数决定):
// 语法:类型[] 变量名 = { 元素1, 元素2, ... };
int[] arr = { 10, 20, 30 };
String[] weekdays = { "Mon", "Tue", "Wed" };
// 等价于(不常用)
int[] arr2 = new int[] { 10, 20, 30 };提示
推荐使用 类型[] 的声明方式,与「数组类型」的读法一致(如「int 数组」),也便于与 C 风格 类型 变量[] 区分。
注意
数组长度在创建时确定,之后不能改变。需要「变长」时,应使用 List 等集合类型。
访问与长度
通过索引(从 0 开始)访问元素,通过 数组名.length 获取长度(只读,不是方法调用)。
基本用法
int[] arr = { 10, 20, 30 };
// 读
int first = arr[0]; // 10
int last = arr[2]; // 30(最后一个元素索引为 length - 1)
// 写
arr[1] = 25; // 将索引 1 的元素改为 25
// 长度
int len = arr.length; // 3(注意:没有括号,是字段不是方法)索引范围与越界
有效索引范围是 0 ~ length - 1。访问超出该范围时,运行时会抛出 ArrayIndexOutOfBoundsException(非受检异常)。
int[] arr = { 10, 20 };
// arr[2] = 30; // 运行时异常:索引 2 越界(有效索引为 0、1)
// arr[-1]; // 同样越界注意
使用循环遍历时,务必保证索引 i 满足 0 <= i < arr.length,避免越界。增强 for 不会暴露索引,可减少此类错误。
遍历数组
传统 for(需要索引时)
适合需要下标的场景(例如修改元素、按位置判断):
int[] arr = { 10, 20, 30 };
for (int i = 0; i < arr.length; i++) {
System.out.println("索引 " + i + ":" + arr[i]);
}增强 for(只读遍历)
不需要索引、只关心每个元素时,用增强 for 更简洁,且不会越界:
int[] arr = { 10, 20, 30 };
for (int value : arr) {
System.out.println(value);
}提示
增强 for 中的变量(如 value)是循环局部的,对其赋值不会改变数组元素;要修改元素请用传统 for + 索引。
示例:求最大值与求和
int[] scores = { 78, 92, 65, 88, 70 };
// 求最大值
int max = scores[0];
for (int i = 1; i < scores.length; i++) {
if (scores[i] > max) {
max = scores[i];
}
}
System.out.println("最高分:" + max); // 92
// 求和
int sum = 0;
for (int s : scores) {
sum += s;
}
System.out.println("总分:" + sum); // 393默认值
使用 new 类型[长度] 创建数组时,元素会被赋予默认值(与 变量与数据类型 中基本类型、引用类型的默认值一致):
| 元素类型 | 默认值 |
|---|---|
| 整型 (int 等) | 0 |
| 浮点型 | 0.0 |
| 布尔型 | false |
| 字符型 | '\u0000' |
| 引用类型 | null |
int[] a = new int[3]; // { 0, 0, 0 }
boolean[] b = new boolean[2]; // { false, false }
String[] s = new String[2]; // { null, null }使用 { ... } 初始化时,没有「未赋值」的元素,因此不会依赖默认值。
注意
引用类型数组元素默认为 null。若未给某下标赋值就调用其方法(如 names[0].length()),会抛出 NullPointerException。使用前应判断或确保已赋值。
多维数组
Java 中的「多维数组」本质是数组的数组(例如二维数组是「一维数组的数组」)。
声明与创建
// 二维数组:可理解为「多行多列」
int[][] matrix = new int[3][4]; // 3 行 4 列
// 直接初始化
int[][] grid = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};访问与遍历
int[][] grid = { { 1, 2 }, { 3, 4 } };
// 访问:grid[行][列]
int v = grid[0][1]; // 2
// 行数、列数(每行长度可不同,见下文)
int rows = grid.length; // 2
int cols0 = grid[0].length; // 2
// 嵌套循环遍历
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
System.out.print(grid[i][j] + " ");
}
System.out.println();
}不规则数组(每行长度不同)
Java 允许每行长度不同(不规则数组):
// 只指定第一维长度,第二维可分别指定
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 3, 4, 5 };
jagged[2] = new int[] { 6 };
// 遍历时用 arr[i].length 避免越界
for (int i = 0; i < jagged.length; i++) {
for (int j = 0; j < jagged[i].length; j++) {
System.out.print(jagged[i][j] + " ");
}
System.out.println();
}注意事项
注意
- 长度不可变:创建后无法增删元素,只能改已有位置的值;需要动态大小时用 List。
- 索引从 0 开始:有效范围是
0 ~ length - 1,越界会抛出ArrayIndexOutOfBoundsException。 - 引用类型元素:默认值为 null,使用前需判断或赋值,避免
NullPointerException。
提示
- 只读遍历且不需要索引时,优先用增强 for,代码更简洁且不易越界。
- 需要复制数组时,可用
Arrays.copyOf、Arrays.copyOfRange或循环手动复制;直接赋值(arr2 = arr1)只复制引用,两个变量指向同一数组。
相关链接
- 变量与数据类型 — 数组元素类型与默认值
- 流程控制 — for 与增强 for 遍历数组
- 集合概述 — 需要变长容器时使用 List 等集合
- Oracle Java 教程 - 数组