Java 数组 超详细知识点整理
一、数组是什么
- 相同类型数据的有序集合
- 长度固定,一旦创建不可改变
- 属于引用类型(存放在堆内存)
- 下标从 0 开始
定义方式(3种)
// 1. 声明+分配空间
int[] arr = new int[5];
// 2. 声明+初始化
int[] arr = new int[]{1,2,3,4,5};
// 3. 静态初始化(简写)
int[] arr = {1,2,3,4,5};
特点
- 长度固定,不能扩容缩容
- 查找快:通过下标 O(1)
- 增删慢:需要移动元素 O(n)
- 基本类型数组有默认值:
- int → 0
- double → 0.0
- boolean → false
- 引用类型 → null
二、数组内存结构(必须懂)
- 数组对象在堆
- 数组引用变量在栈
- 多个引用可以指向同一个数组对象
- 数组一旦创建,长度不可变
int[] a = {1,2,3};
int[] b = a;
b[0] = 100;
// a[0] 也变成 100
三、数组遍历
1. 普通 for(推荐,可操作下标)
for (int i = 0; i < arr.length; i++) {
arr[i] = ...;
}
2. 增强 for(foreach,只能读)
for (int num : arr) {
System.out.println(num);
}
四、二维数组
本质:数组中存数组
定义
int[][] arr = new int[3][2];
int[][] arr = {{1,2},{3,4},{5,6}};
遍历
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
...
}
}
五、Arrays 工具类(开发必用)
import java.util.Arrays;
常用方法:
Arrays.toString(arr)→ 打印数组Arrays.sort(arr)→ 升序排序Arrays.binarySearch(arr, key)→ 二分查找(必须先排序)Arrays.copyOf(arr, newLength)→ 复制数组(实现扩容)Arrays.copyOfRange(arr, from, to)→ 区间复制Arrays.fill(arr, val)→ 填充Arrays.equals(arr1, arr2)→ 比较内容是否相同
六、数组常见操作
1. 数组扩容
数组长度不可变,只能新建更大数组+拷贝
int[] newArr = Arrays.copyOf(arr, arr.length * 2);
2. 数组反转
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;
}
3. 求最值
int max = arr[0];
for (int num : arr) {
if (num > max) max = num;
}
七、企业开发真实坑(非常重要)
坑1:数组下标越界异常 ArrayIndexOutOfBoundsException
- 访问
arr[-1]、arr[arr.length] - 循环条件写错:
i <= arr.length - 企业高频线上BUG
坑2:空指针 NullPointerException
int[] arr = null;
arr.length; // NPE
坑3:增强for循环不能修改数组元素
下面代码无效:
for (int num : arr) {
num = 100; // 只修改副本,数组不变
}
坑4:数组赋值是引用传递
int[] a = {1,2};
int[] b = a;
b[0] = 100;
// a 也被改了,业务数据被污染
坑5:数组转ArrayList 陷阱
List<int[]> list = Arrays.asList(arr);
- 基本类型数组会被当作一个元素
- 正确写法:使用包装类
Integer[]
坑6:asList 返回的集合不能增删
List<String> list = Arrays.asList(strArr);
list.add("xxx"); // 报错:UnsupportedOperationException
原因:返回的是 Arrays 内部类,没有实现增删方法
坑7:二分查找必须先排序
不排序会导致结果错误,很难排查
坑8:数组默认值引发业务BUG
- int 数组未赋值默认为 0
- 业务中 0 可能是合法值,导致逻辑判断错误
- 引用类型数组默认为 null,遍历时容易 NPE
坑9:二维数组长度混乱
int[][] arr = new int[3][];
arr[0].length; // NPE,因为 arr[0] 是 null
坑10:大量使用数组导致代码臃肿
企业开发:
- 存储数据优先用 ArrayList(自动扩容、方法丰富)
- 数组一般用于底层、高性能场景
八、数组 vs ArrayList(面试必考)
| 数组 | ArrayList |
|---|---|
| 长度固定 | 动态扩容 |
| 基本类型+引用类型 | 只能存引用类型 |
| 性能略高 | 性能稍低但开发效率极高 |
| 无内置方法 | 丰富API(add/remove/clear) |
九、总结一句话
数组是固定长度、有序、查找快的引用类型,开发中尽量用 ArrayList 替代; 高频坑:下标越界、空指针、引用传递、asList 陷阱、foreach 不能赋值。