05、Java 基础硬核复习:数组的本质与面试考点
第一部分:核心知识体系
1. 数组概述
数组是存储同类型数据的连续内存块,通过索引(下标)快速访问元素。其核心特点包括:
- 长度固定:创建后无法动态改变大小(需通过新建数组+复制实现扩容)。
- 类型一致:所有元素必须为同一数据类型(基本类型或引用类型)。
- 索引访问:通过
数组名[索引]访问元素,索引从 0 开始。
2. 一维数组的基本使用
(1)初始化方式
-
静态初始化:直接指定元素值,长度由元素个数决定。
javaint[] arr1 = new int[]{1, 2, 3}; // 或简化为 int[] arr1 = {1, 2, 3}; -
动态初始化 :指定长度,元素默认初始化(如
int类型默认为 0)。javaint[] arr2 = new int[3]; // arr2 = [0, 0, 0]
(2)核心操作
-
长度 :通过
数组名.length获取(如arr1.length为 3)。 -
元素访问 :通过索引访问(如
arr1[0]为 1)。 -
遍历 :使用
for循环或foreach(增强 for 循环)。javafor (int num : arr1) { System.out.println(num); }
3. 二维数组的基本使用
二维数组本质是"数组的数组",即每个元素是一维数组。
(1)初始化方式
-
静态初始化:直接指定行和列的元素值。
javaint[][] arr3 = new int[][]{{1, 2}, {3}}; // 或简化为 {{1,2},{3}} -
动态初始化:指定行数和列数,元素默认初始化。
javaint[][] arr4 = new int[2][3]; // arr4 = [[0,0,0], [0,0,0]]
(2)核心操作
-
长度 :
arr3.length为行数(2),arr3[0].length为第一行的列数(2)。 -
遍历:通过嵌套循环访问每个元素。
javafor (int i = 0; i < arr3.length; i++) { for (int j = 0; j < arr3[i].length; j++) { System.out.print(arr3[i][j] + " "); } }
4. 元素默认初始化值
- 基本类型 :
int/short/long为 0,double/float为 0.0,boolean为false,char为'\u0000'(空字符)。 - 引用类型 :所有引用类型(如
String、自定义类)默认为null。
5. 数组的常见算法
(1)特征值计算
-
求和、平均值、最大值、最小值:通过遍历数组累加或比较得到。
javaint sum = 0; for (int num : arr1) { sum += num; }
(2)赋值与复制
-
直接赋值:引用传递(修改副本会影响原数组)。
javaint[] arr5 = arr1; // arr5 和 arr1 指向同一内存地址 arr5[0] = 10; // arr1[0] 也变为 10 -
深拷贝 :通过
Arrays.copyOf()或clone()创建新数组(修改副本不影响原数组)。javaint[] arr6 = Arrays.copyOf(arr1, arr1.length); arr6[0] = 20; // arr1[0] 仍为 10
(3)反转与扩容
-
反转 :从数组两端交换元素(如
arr1[0]与arr1[2]交换)。 -
扩容 :新建更大长度的数组,通过
System.arraycopy()或Arrays.copyOf()复制原数组元素。javaint[] newArr = Arrays.copyOf(arr1, arr1.length + 1); // 扩容 1 位
(4)查找与排序
- 顺序查找:遍历数组,适用于无序数组(时间复杂度 O(n))。
- 二分查找:前提是数组有序,通过不断缩小范围查找(时间复杂度 O(log n))。
- 排序算法 :
- 冒泡排序:相邻元素比较,大的后移(稳定,时间复杂度 O(n²))。
- 快速排序:分治法,选基准分区(平均时间复杂度 O(n log n))。
6. Arrays 工具类
Java 提供的数组操作工具类,常用方法包括:
Arrays.sort(arr):排序(基本类型默认升序)。Arrays.binarySearch(arr, target):二分查找(需先排序)。Arrays.toString(arr):打印数组内容(如[1, 2, 3])。Arrays.copyOf(arr, newLength):复制数组(可扩容/缩容)。
第二部分:高频面试考点
1. 数组初始化的区别
- 静态 vs 动态:静态初始化直接赋值,长度由元素个数决定;动态初始化指定长度,元素默认初始化。
- 面试陷阱 :动态初始化后未赋值直接使用(如
int[] arr = new int[3]; System.out.println(arr[0]);输出 0,而非报错)。
2. 内存解析:一维 vs 二维数组
- 一维数组 :连续内存块,元素紧密排列(如
int[] arr = {1,2,3}在内存中连续存储 1、2、3)。 - 二维数组 :数组元素是一维数组,每个一维数组独立存储(如
int[][] arr = {``{1,2}, {3,4}}中,arr[0]和arr[1]是两个独立的内存块)。 - 面试陷阱 :二维数组行长度可不同(如
int[][] arr = new int[2][]; arr[0] = new int[3]; arr[1] = new int[2];),需注意遍历时的列长度判断。
3. 常见算法的手写实现
- 冒泡排序 :需掌握相邻元素比较的逻辑,注意边界条件(如
j < arr.length - 1 - i)。 - 快速排序:需理解分治思想(选基准、分区、递归),面试常考其时间复杂度和稳定性(不稳定)。
- 二分查找 :需注意数组必须有序,否则结果不可靠;返回值为
-(插入点+1)(未找到时)。
4. Arrays 工具类的异常
- 空指针异常(NullPointerException) :对
null数组调用Arrays.sort()或toString()时抛出。 - 角标越界异常(ArrayIndexOutOfBoundsException) :访问索引超出
length-1(如arr[3]对长度为 3 的数组)。 - 面试陷阱 :
binarySearch前未排序会导致结果错误(如对[3,1,2]调用binarySearch(1)可能返回错误索引)。
5. 数组复制的深浅拷贝
- 浅拷贝(直接赋值):引用传递,修改副本会影响原数组。
- 深拷贝(Arrays.copyOf/clone):创建新数组,修改副本不影响原数组。
- 面试陷阱:混淆两者,导致数据意外修改(如将原数组传递给方法后,方法内修改了副本,原数组也被修改)。
总结
数组是 Java 编程的基石,掌握其初始化、内存布局及常见算法是面试的核心要求。通过理解底层逻辑(如连续内存、引用传递),能快速定位问题并写出高效代码。基础不牢,地动山摇,扎实掌握数组知识将为后续学习集合框架、算法打下坚实基础。