Java 数组详解
数组是 Java 中最基础、最重要的数据结构之一,它用于存储固定大小 的同类型元素的有序集合。
1. 数组的核心特性
- 长度固定:一旦创建,数组容量不可改变。
- 类型一致:所有元素必须是相同的数据类型(基本类型或引用类型)。
- 连续内存:元素在内存中按顺序紧密排列,访问速度快。
- 索引从 0 开始 :第一个元素的索引是 0,最后一个元素的索引是
length - 1。
2. 声明数组
声明数组时只需指定元素类型和数组名,不分配内存。
java
// 推荐写法
int[] arr1;
double[] arr2;
String[] arr3;
// 不推荐但合法的写法(C/C++风格)
int arr4[];
3. 创建数组(分配内存)
使用 new 关键字分配固定大小的数组,元素会被赋予默认值(数值类型为 0,boolean 为 false,引用类型为 null)。
java
int[] arr = new int[5]; // 创建一个能存5个int的数组,默认值均为0
4. 初始化数组
-
静态初始化:创建时直接指定元素值,长度由编译器自动计算。
javaint[] arr = {1, 2, 3, 4, 5}; String[] names = new String[]{"Alice", "Bob", "Charlie"}; -
动态初始化:先创建数组,之后单独为每个元素赋值。
javaint[] arr = new int[3]; arr[0] = 10; arr[1] = 20; arr[2] = 30;
5. 访问与修改元素
通过索引访问元素,索引必须在 [0, length-1] 范围内,否则抛出 ArrayIndexOutOfBoundsException。
java
int[] arr = {1, 2, 3};
int first = arr[0]; // 1
arr[1] = 99; // 修改第二个元素为99
6. 数组的长度属性
每个数组都有一个 length 属性(注意不是方法),用于获取数组容量。
java
int size = arr.length; // 返回数组的长度
7. 遍历数组
-
普通 for 循环:可控制索引。
javafor (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } -
增强 for 循环(for-each):简洁,但不能获取索引,也不能修改元素值。
javafor (int num : arr) { System.out.println(num); } -
使用
java.util.Arrays.toString:快速打印数组内容。javaSystem.out.println(Arrays.toString(arr));
8. 多维数组
Java 中的多维数组本质上是"数组的数组"。例如二维数组可以看作一个一维数组,其每个元素又是一个一维数组。
java
// 创建并初始化
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 动态创建(3行4列)
int[][] table = new int[3][4];
// 不规则数组(每行长度可以不同)
int[][] ragged = new int[3][];
ragged[0] = new int[2];
ragged[1] = new int[3];
ragged[2] = new int[1];
// 访问元素
int val = matrix[1][2]; // 6
9. 数组工具类 java.util.Arrays
Java 提供了丰富的静态方法方便操作数组:
| 方法 | 说明 |
|---|---|
Arrays.toString(arr) |
返回数组的字符串表示 |
Arrays.sort(arr) |
对数组进行升序排序 |
Arrays.binarySearch(arr, key) |
二分查找(数组必须已排序) |
Arrays.fill(arr, val) |
将数组所有元素填充为 val |
Arrays.copyOf(arr, newLength) |
复制数组,可改变长度 |
Arrays.equals(arr1, arr2) |
比较两个数组是否相等 |
Arrays.deepToString(arr2d) |
打印多维数组 |
java
int[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr); // [1, 1, 3, 4, 5]
int index = Arrays.binarySearch(arr, 3); // 2
int[] copy = Arrays.copyOf(arr, 10); // 扩容,多出位置补0
10. 数组的局限与替代方案
- 缺点:长度固定,无法动态增删元素;插入/删除操作效率低(需要移动元素)。
- 替代方案 :
java.util.ArrayList实现了可变长度的动态数组,提供了更丰富的方法(add、remove、contains等)。
java
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.remove(0);
11. 注意事项
- 数组变量是引用类型,赋值时只复制引用,不复制元素(浅拷贝)。
- 使用
= { ... }静态初始化只能在声明语句中直接使用。 - 方法可以返回数组,作为参数传递时,方法内对数组元素的修改会影响原始数组。
- 多维数组中,每个子数组可以长度不同,称为"不规则数组"或"锯齿数组"。
12. 经典示例:查找与统计
java
int[] scores = {88, 72, 93, 66, 85};
int sum = 0, max = scores[0];
for (int score : scores) {
sum += score;
if (score > max) max = score;
}
double average = (double) sum / scores.length;
System.out.printf("平均分: %.2f, 最高分: %d", average, max);