Java数组使用指南:从语法、初始化到常见操作与排错
Java数组是存储相同类型元素的固定大小连续集合,具有自动编号(从0开始)的优势。本文梳理了数组的声明与初始化规范,详述了遍历、排序(选择/冒泡)、查找(二分法)及二维数组操作的实现逻辑,并针对常见的越界与空指针异常提供排查思路。
一、数组的核心特性与优势
数组在Java中用于解决大量同类型数据的存储问题。相比单独定义变量,数组的最大优势在于为存储的元素分配连续的内存空间,并提供基于索引(从0开始)的快速访问机制。例如,通过学号(索引)可直接定位对应的学生信息。
与集合类相比,数组具有以下特点:
- 类型固定:数组一旦创建,大小不可修改,且只能保存特定类型的元素。
- 内存存储:原生数据类型数组直接存储值;对象数组和集合则存储对象的引用。
- 边界检查:任何越界操作都会触发
ArrayIndexOutOfBoundsException运行时异常。
若需在集合中存储原生类型(如int),需使用包装类(如Integer)进行转换,但这增加了复杂度,因此在仅需固定容量存储时,数组更为高效。
二、数组的声明、创建与初始化
第1步:声明数组变量
声明数组需明确元素类型。推荐使用 int[] arrName 而非 int arrName[],前者能更清晰地表明这是一个数组类型。
// 推荐写法
int[] arr;
// 也可写作 int arr[]; (不推荐)
第2步:分配内存空间(创建)
使用 new 关键字在堆内存中开辟容器。例如 arr = new int[5]; 表示创建一个可容纳5个整数的数组。此时数组元素已存在,但默认值为该类型的默认值(int为0)。
第3步:初始化数据
初始化分为静态与动态两种方式:
- 静态初始化:声明与赋值在同一语句完成,系统自动计算长度。
int[] arr1 = {1, 2, 3, 4, 5}; // 注意:不能分开写为 arr = {1,2}; 这会引发编译错误 - 动态初始化:先指定长度,再逐个赋值。
int[] arr2 = new int[]{1, 2, 3, 4, 5}; // 或 int[] arr3 = new int[3]; arr3[0] = 1; arr3[1] = 5;
三、数组的基本操作
第1步:数组遍历
获取数组长度的属性为 .length(注意不是方法)。遍历通常结合for循环使用:
public static void printArray(int[] x) {
for (int y = 0; y < x.length; y++) {
System.out.println("x[" + y + "] = " + x[y]);
}
}
第2步:获取最大值
思路:设定一个初始最大值变量(通常为第一个元素),遍历数组进行对比,更新较大值。
public static int getMax(int[] arr) {
if (arr == null || arr.length == 0) return -1;
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
第3步:数组排序算法
1. 选择排序(直接排序):
每次从未排序序列中找到最小(大)元素,存放到排序序列的起始位置。内层循环比较从当前角标的下一个元素开始。
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
2. 冒泡排序:
相邻两个元素两两比较,若顺序错误则交换。每轮结束会将最大元素“沉”到最后。
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
// -x: 减少参与比较次数; -1: 防止arr[y+1]越界
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
第4步:查找与翻转
1. 折半查找(二分法):
前提:数组必须是有序的。效率远高于线性查找。
逻辑:维护最小(min)、最大(max)和中点(mid)索引,根据目标值与中间值的比较结果缩小查找范围。
public static int halfSearch(int[] arr, int key) {
int min = 0, max = arr.length - 1, mid;
while (min <= max) {
mid = (max + min) / 2;
if (key > arr[mid]) {
min = mid + 1;
} else if (key < arr[mid]) {
max = mid - 1;
} else {
return mid; // 找到返回索引
}
}
return -1; // 未找到
}
2. 数组翻转:
双指针法:头指针(start)指向起始,尾指针(end)指向末尾,交换两端元素并向中心移动,直到两指针相遇。
public static void reverseArray(int[] arr) {
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
swap(arr, start, end);
}
}
private static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
四、二维数组处理
二维数组本质上是“数组的数组”。其定义为 type[][] name。
第1步:二维数组的声明与初始化
静态初始化示例:
int[][] a = {{1, 2}, {3, 4, 5}, {6}};
// 注意:各一维数组长度可以不同
第2步:遍历与运算
遍历需要双层嵌套循环。外层控制行(一维数组),内层控制列(具体元素)。
// 示例:遍历并求和
public static long getSum(int[][] a) {
long sum = 0L;
for (int i = 0; i < a.length; i++) { // 遍历每一行
for (int j = 0; j < a[i].length; j++) { // 遍历该行的每个元素
sum += a[i][j];
}
}
return sum;
}
其中 a.length 表示二维数组的行数,a[i].length 表示第 i 行的列数。
五、常见异常与排查
1. 角标越界 (ArrayIndexOutOfBoundsException)
原因:访问的索引小于0或大于等于数组长度。例如长度为3的数组,索引应为0,1,2。访问 arr[3] 即报错。
预防:循环条件严格使用 < array.length,避免手动硬编码上限。
2. 空指针异常 (NullPointerException)
原因:数组引用指向null时仍尝试访问元素。
int[] arr = null;
System.out.println(arr[0]); // 抛出 NullPointerException
预防:在使用数组前检查 arr != null;或者在初始化后不要意外地将变量赋值为null。
六、工具类 Arrays 补充
Java提供 java.util.Arrays 类简化常用操作:
Arrays.toString(arr):便捷打印数组内容。Arrays.sort(arr):对数组进行升序排序(底层通常采用优化后的快速排序或归并排序)。Arrays.binarySearch(arr, key):二分查找。**注意**:使用前必须先调用sort排序,否则结果不可靠。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









