Skip to content
第 12 / 250 章后端⏱ 10 分钟阅读

第 12 章:数组

学习目标

  • 掌握一维、二维数组的声明和使用
  • 学会 Arrays 工具类的常用方法
  • 理解数组与 List 的互转
  • 避免数组的常见坑

一、什么是数组?

数组 = 相同类型数据的有序集合,长度固定。

java
int[] scores = {85, 92, 78, 95, 88};
//  ↓  ↓                                ↓
// 类型 引用  5 个 int 元素

二、一维数组

2.1 声明方式(两种)

java
// ✅ 推荐:类型在前
int[] arr1;

// ⚠️ C 风格:可读性差
int arr2[];

2.2 创建数组

java
// 方式 1:声明时初始化(最常用)
int[] scores = {85, 92, 78, 95, 88};

// 方式 2:new + 初始化器(适合动态数据)
int[] ages = new int[]{18, 25, 30};

// 方式 3:new + 指定长度(默认 0)
int[] arr = new int[5];  // 5 个 0
String[] names = new String[3];  // 3 个 null

// 方式 4:先声明再创建
int[] nums;
nums = new int[10];

2.3 访问元素

java
int[] arr = {10, 20, 30, 40, 50};

System.out.println(arr[0]);     // 10(第一个元素)
System.out.println(arr[4]);     // 50(最后一个元素)
arr[0] = 100;                  // 修改第一个元素
// arr[5] = 60;                // ❌ ArrayIndexOutOfBoundsException

2.4 数组长度

java
int[] arr = {10, 20, 30};
System.out.println(arr.length);  // 3(数组 length 是属性,不是方法)

三、二维数组

二维数组是"数组的数组"。

java
// 声明
int[][] matrix;

// 创建 3×4 矩阵
matrix = new int[3][4];

// 声明并初始化
int[][] matrix2 = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

// 访问
System.out.println(matrix2[0][0]);  // 1
System.out.println(matrix2[1][2]);  // 7
matrix2[2][3] = 100;

3.1 不规则二维数组

java
// 每行长度可以不同
int[][] jagged = {
    {1, 2},
    {3, 4, 5, 6},
    {7}
};

System.out.println(jagged[0].length);  // 2
System.out.println(jagged[1].length);  // 4
System.out.println(jagged[2].length);  // 1

四、数组的内存模型

关键点

  • 数组是引用类型,引用在栈
  • 实际数据在堆
  • 一旦创建,长度不可变

五、数组遍历

5.1 for 循环(经典)

java
int[] arr = {85, 92, 78, 95, 88};
for (int i = 0; i < arr.length; i++) {
    System.out.println("arr[" + i + "] = " + arr[i]);
}

5.2 for-each(推荐)

java
for (int score : arr) {
    System.out.println(score);
}

5.3 二维数组遍历

java
int[][] matrix = {{1, 2, 3}, {4, 5, 6}};
for (int[] row : matrix) {           // ① 外层遍历行
    for (int num : row) {             // ② 内层遍历每行元素
        System.out.print(num + " ");
    }
    System.out.println();
}

六、Arrays 工具类

java.util.Arrays 提供大量数组操作方法。

6.1 打印数组

java
int[] arr = {3, 1, 4, 1, 5, 9, 2, 6};
System.out.println(Arrays.toString(arr));
// [3, 1, 4, 1, 5, 9, 2, 6]

int[][] matrix = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(matrix));
// [[1, 2], [3, 4]]

6.2 排序

java
int[] arr = {3, 1, 4, 1, 5, 9, 2, 6};
Arrays.sort(arr);  // 升序排序(双轴快排 + TimSort)
System.out.println(Arrays.toString(arr));
// [1, 1, 2, 3, 4, 5, 6, 9]

6.3 填充

java
int[] arr = new int[5];
Arrays.fill(arr, 100);
System.out.println(Arrays.toString(arr));
// [100, 100, 100, 100, 100]

6.4 二分查找(必须先排序)

java
int[] arr = {1, 3, 5, 7, 9, 11};
int index = Arrays.binarySearch(arr, 7);   // 3
int notFound = Arrays.binarySearch(arr, 4); // -3(负数表示未找到)

6.5 比较

java
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(Arrays.equals(a, b));      // true(值相等)
System.out.println(a.equals(b));              // false(继承 Object 的 == 比较)

6.6 复制

java
int[] arr = {1, 2, 3, 4, 5};

int[] copy1 = Arrays.copyOf(arr, 5);       // 复制前 5 个
int[] copy2 = Arrays.copyOfRange(arr, 1, 4); // 复制 [1, 4)
int[] copy3 = arr.clone();                  // 浅拷贝

七、数组与 List 互转

7.1 数组 → List

java
String[] arr = {"a", "b", "c"};

// ✅ JDK 9+ 推荐
List<String> list1 = Arrays.asList(arr);          // 固定大小 List
List<String> list2 = List.of(arr);                // 不可变 List

// ✅ 可变 List
List<String> list3 = new ArrayList<>(Arrays.asList(arr));

⚠️ Arrays.asList() 返回的 List 长度固定,不能 add/remove。

7.2 List → 数组

java
List<String> list = List.of("a", "b", "c");

String[] arr1 = list.toArray(new String[0]);    // ✅ 推荐
String[] arr2 = list.toArray(new String[list.size()]);

八、数组的常见坑

8.1 数组越界

java
int[] arr = {1, 2, 3};
// arr[3] = 4;   // ❌ ArrayIndexOutOfBoundsException(下标越界)

8.2 空指针

java
int[] arr = null;
System.out.println(arr.length);  // ❌ NullPointerException

8.3 长度不可变

java
int[] arr = {1, 2, 3};
// arr.length = 5;   // ❌ 编译报错:length 是 final

8.4 默认值陷阱

java
// 基本类型数组:默认 0 / false
int[] nums = new int[3];
System.out.println(nums[0]);  // 0(不是 null)

// 引用类型数组:默认 null
String[] strs = new String[3];
System.out.println(strs[0]);  // null

九、完整代码示例

java
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

/**
 * 数组综合示例
 *
 * 配套文档:第 12 章 数组
 * 运行方式:javac ArrayDemo.java && java ArrayDemo
 */
public class ArrayDemo {
    public static void main(String[] args) {

        // ============ 1. 一维数组 ============
        System.out.println("=== 一维数组 ===");
        int[] scores = {85, 92, 78, 95, 88};

        System.out.println("长度: " + scores.length);
        System.out.println("第一个: " + scores[0]);
        System.out.println("最后一个: " + scores[scores.length - 1]);

        // 修改元素
        scores[0] = 100;
        System.out.println("修改后: " + Arrays.toString(scores));

        // ============ 2. 遍历 ============
        System.out.println("\n=== 遍历 ===");
        for (int i = 0; i < scores.length; i++) {
            System.out.println("for [" + i + "] = " + scores[i]);
        }
        System.out.println("---");
        for (int score : scores) {
            System.out.println("for-each = " + score);
        }

        // ============ 3. 二维数组 ============
        System.out.println("\n=== 二维数组 ===");
        int[][] matrix = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        };
        System.out.println("行数: " + matrix.length);
        System.out.println("第一行列数: " + matrix[0].length);
        System.out.println("matrix[1][2] = " + matrix[1][2]);  // 7

        // 遍历二维数组
        for (int[] row : matrix) {
            for (int num : row) {
                System.out.printf("%4d", num);
            }
            System.out.println();
        }

        // ============ 4. Arrays 工具类 ============
        System.out.println("\n=== Arrays 工具类 ===");
        int[] arr = {3, 1, 4, 1, 5, 9, 2, 6};
        System.out.println("原数组: " + Arrays.toString(arr));

        Arrays.sort(arr);
        System.out.println("排序后: " + Arrays.toString(arr));

        Arrays.fill(arr, 0);
        System.out.println("填充后: " + Arrays.toString(arr));

        // ============ 5. 数组与 List 互转 ============
        System.out.println("\n=== 数组与 List 互转 ===");
        String[] strArr = {"a", "b", "c"};

        // 数组 → List
        List<String> list1 = new ArrayList<>(Arrays.asList(strArr));
        list1.add("d");  // ✅ 可变 List
        System.out.println("List: " + list1);

        // List → 数组
        String[] newArr = list1.toArray(new String[0]);
        System.out.println("Array: " + Arrays.toString(newArr));

        // ============ 6. 实战:找数组中的最大值 ============
        System.out.println("\n=== 实战:数组操作 ===");
        int[] data = {23, 45, 12, 67, 34, 89, 5};
        int max = data[0];
        int min = data[0];
        int sum = 0;
        for (int n : data) {
            if (n > max) max = n;
            if (n < min) min = n;
            sum += n;
        }
        double avg = (double) sum / data.length;

        System.out.println("最大值: " + max);
        System.out.println("最小值: " + min);
        System.out.println("总和: " + sum);
        System.out.println("平均值: " + avg);
    }
}

运行结果

=== 一维数组 ===
长度: 5
第一个: 85
最后一个: 88
修改后: [100, 92, 78, 95, 88]
...

十、动手练习

练习 1:基础题

写一个 ArrayUtils 类,实现:

java
public static int max(int[] arr)         // 最大值
public static int min(int[] arr)         // 最小值
public static double average(int[] arr)  // 平均值
public static int[] reverse(int[] arr)   // 反转

练习 2:进阶题

实现数组去重(保留第一次出现的元素顺序):

java
int[] input = {1, 2, 3, 2, 1, 4, 5, 4};
int[] output = unique(input);
// 输出: [1, 2, 3, 4, 5]

练习 3:挑战题

实现一个学生成绩统计小项目:

=== 成绩统计 ===
请输入学生人数:5
请输入 5 个成绩(0-100):
张三 85
李四 92
王五 78
赵六 95
钱七 88

=== 统计结果 ===
平均分:87.6
最高分:95(赵六)
最低分:78(王五)
及格人数:4
优秀人数(>=90):2

十一、本章小结

要点关键
数组本质固定长度的同类数据集合
声明方式int[] arr(推荐)或 int arr[]
内存模型引用在栈,数据在堆
遍历方式for / for-each
工具类Arrays.sortArrays.toStringArrays.binarySearch
数组转 ListArrays.asList()(长度固定)或 new ArrayList<>()
常见坑越界、空指针、长度不可变

推荐阅读


下一章第 13 章:面向对象思想

本站基于 VitePress 构建 · 由 Codebook 团队维护