第一部分:二维数组基础概念

二维数组即“数组的数组”,常用于表示矩阵、表格等二维结构

学习目标

  • 理解二维数组的内存模型
  • 区分数组长度、行数、列数
  • 掌握三种声明语法

内存结构示意

[
1
2
3
4
5
6
]

int[][] a = {{1,2,3}, {4,5,6}};

关键术语

  • 行(row):第一维长度 length
  • 列(column):第二维长度 a[0].length
  • 元素访问a[row][col]

第二部分:二维数组创建与初始化

1

声明语法(三种写法)

// 推荐写法
int[][] matrix1;
double[][] scores;

// C 风格(不推荐)
int matrix2[][];

// 混合写法
int[] rowVector[];
2

动态初始化

// 3行4列的整型矩阵,默认值为0
int[][] grid = new int[3][4];

// 不规则数组需要先指定行数
int[][] triangle = new int[5][]; // 列稍后指定
3

静态初始化

// 完整写法
int[][] a = new int[][] {
    {1, 2, 3},
    {4, 5, 6}
};

// 简化写法(推荐)
int[][] b = {
    {1, 2},
    {3, 4},
    {5, 6}
};

第三部分:访问、修改与遍历

1

读写元素

int[][] m = new int[2][3];

// 写入
m[0][0] = 100;
m[1][2] = 200;

// 读取
int val = m[0][0]; // 100

// 获取维度信息
int rows = m.length; // 2
int cols = m[0].length; // 3
2

嵌套循环遍历

int[][] table = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 按行遍历
for (int i = 0; i < table.length; i++) {
    for (int j = 0; j < table[i].length; j++) {
        System.out.print(table[i][j] + " ");
    }
    System.out.println();
}

// 增强for循环
for (int[] row : table) {
    for (int val : row) {
        System.out.print(val + " ");
    }
    System.out.println();
}
3

列求和示例

int[][] data = {
    {1, 2, 3},
    {4, 5, 6}
};

// 计算每列之和
int[] colSum = new int[data[0].length];
for (int j = 0; j < data[0].length; j++) {
    int sum = 0;
    for (int i = 0; i < data.length; i++) {
        sum += data[i][j];
    }
    colSum[j] = sum;
}
System.out.println(Arrays.toString(colSum)); // [5, 7, 9]

第四部分:不规则(锯齿)数组

每行列数可变的二维数组

1

创建锯齿数组

// 创建5行的三角形数组
int[][] triangle = new int[5][];

for (int i = 0; i < triangle.length; i++) {
    triangle[i] = new int[i + 1]; // 第i行有i+1列
}

// 填充杨辉三角
for (int i = 0; i < triangle.length; i++) {
    triangle[i][0] = triangle[i][i] = 1;
    for (int j = 1; j < i; j++) {
        triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
    }
}

第五部分:Arrays 工具类全览

java.util.Arrays 提供的静态方法让数组操作更高效

排序 sort

Arrays.sort(int[] a) // 升序 Arrays.sort(int[] a, int fromIndex, int toIndex)
int[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr); // [1, 1, 3, 4, 5]
Arrays.sort(arr, 1, 4); // 部分排序

// 二维数组按第一列排序
int[][] points = {{3,4}, {1,2}};
Arrays.sort(points, (a,b) -> a[0] - b[0]);

查找 binarySearch

int binarySearch(int[] a, int key)
int[] sorted = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(sorted, 5); // 2
int missing = Arrays.binarySearch(sorted, 4); // -3 (插入点)

复制 copyOf / copyOfRange

int[] src = {10, 20, 30, 40};
int[] copy = Arrays.copyOf(src, src.length); // 完全复制
int[] part = Arrays.copyOfRange(src, 1, 3); // [20, 30]

比较 equals / deepEquals

int[] a = {1,2,3};
int[] b = {1,2,3};
boolean same = Arrays.equals(a, b); // true

int[][] aa = {{1}, {2}};
int[][] bb = {{1}, {2}};
boolean deep = Arrays.deepEquals(aa, bb); // true

填充 fill

int[] arr = new int[5];
Arrays.fill(arr, 99); // [99,99,99,99,99]
Arrays.fill(arr, 1, 4, 77); // [99,77,77,77,99]

转字符串 toString / deepToString

int[] nums = {1,2,3};
System.out.println(Arrays.toString(nums)); // [1, 2, 3]

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

第六部分:二维数组常见错误

错误1:NullPointerException

int[][] arr = new int[3][]; // 只创建了行,列仍为null
arr[0][0] = 10; // NullPointerException
for (int i = 0; i < arr.length; i++) {
    arr[i] = new int[4]; // 初始化每一行
}

错误2:ArrayIndexOutOfBoundsException

int[][] a = {
    {1,2},
    {3}
};
int val = a[1][1]; // 越界

错误3:深浅拷贝混淆

int[][] original = {{1,2}, {3,4}};
int[][] copy = original.clone(); // 仅复制引用
copy[0][0] = 99; // original也会被修改
int[][] deep = Arrays.stream(original)
    .map(r -> r.clone())
    .toArray(int[][]::new);

第七部分:综合实战

实战:学生成绩管理系统

import java.util.*;

public class ScoreManager {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("学生人数: "); int stu = sc.nextInt();
        System.out.print("课程门数: "); int course = sc.nextInt();

        double[][] scores = new double[stu][course];

        // 输入成绩
        for (int i = 0; i < stu; i++) {
            for (int j = 0; j < course; j++) {
                scores[i][j] = sc.nextDouble();
            }
        }

        // 计算每学生平均分
        double[] stuAvg = new double[stu];
        for (int i = 0; i < stu; i++) {
            stuAvg[i] = Arrays.stream(scores[i]).average().orElse(0);
        }

        System.out.println("学生平均分: " + Arrays.toString(stuAvg));
    }
}

学习总结

  • 二维数组本质是一维数组的数组
  • 遍历二维数组务必使用嵌套循环
  • 不规则数组可节省内存
  • Arrays 工具类极大简化开发
  • 注意深浅拷贝和越界问题