Java 多维数组
数组是存储相同类型数据集合的强大工具。在此之前,你主要接触的是一维数组,它们就像简单的列表或数据行。然而,许多现实场景需要表示具有多个维度的数据,例如表格、网格甚至更复杂的结构。
这就是多维数组发挥作用的地方。多维数组允许你按行和列(甚至更复杂的层级)组织数据,从而更轻松地建模和操作结构化信息。
1. 理解多维数组
多维数组本质上是数组的数组。最常见的多维数组是二维(2D)数组,你可以将其想象为一个带有行和列的网格或表格。
虽然 Java 在技术上并不直接支持真正的多维数组,但它允许你创建一个数组,其中的每个元素本身也是一个数组。这在效果上模拟出了多维结构。
想象一下电子表格:它有行和列,每个单元格保存一个数据。二维数组的工作方式与之类似,你需要指定行索引和列索引来访问特定的数据。
2. 声明和初始化二维数组
要声明二维数组,你需要使用两组方括号 [],每一组代表一个维度。
2.1 声明语法
声明二维数组的基本语法如下:
数据类型[][] 数组名;例如,声明一个整数类型的二维数组(矩阵):
int[][] matrix;2.2 初始化数组大小
初始化二维数组时,你需要指定每个维度的长度。对于二维数组,这意味着要指定行数和列数。
// 声明并初始化一个 3 行 4 列的二维数组
int[][] matrix = new int[3][4];这会创建一个名为 matrix 的二维数组,其中所有元素都被初始化为默认值(int 为 0,对象为 null,boolean 为 false 等)。
2.3 使用初始化列表
你也可以在声明的同时直接赋值,这与一维数组类似。每一组内部的大括号 {} 代表一行。
// 直接初始化二维数组
int[][] grades = {
{90, 85, 92}, // 学生 1 的成绩(如:数学、科学、英语)
{78, 88, 80}, // 学生 2 的成绩
{95, 90, 87} // 学生 3 的成绩
};在这个例子中,grades 是一个 3 行 3 列的数组。每一行代表一个学生,每一列代表一个科目的成绩。
3. 交错数组 (Jagged Arrays)
Java “数组的数组”这种设计带来了一个强大的特性:交错数组(也称为不规则数组)。这意味着内部数组(即每一行)的长度可以不同。当你的数据行长短不一时,这种灵活性非常有用。
要创建交错数组,你在初始化外部数组时只指定行数,然后分别为每一行初始化不同的长度:
// 声明一个有 3 行的二维数组,列数稍后设置
int[][] irregularMatrix = new int[3][];
// 为每一行初始化不同的列数
irregularMatrix[0] = new int[5]; // 第一行有 5 列
irregularMatrix[1] = new int[2]; // 第二行有 2 列
irregularMatrix[2] = new int[4]; // 第三行有 4 列这种灵活性是因为在 Java 中,二维数组实际上是一个存放引用的数组,每个引用指向另一个不同大小的一维数组。
4. 访问多维数组中的元素
要访问二维数组中的特定元素,你需要提供两个索引:行索引和列索引。和一维数组一样,索引是从 0 开始的。
语法如下:数组名[行索引][列索引]
让我们以 grades 数组为例:
int[][] grades = {
{90, 85, 92},
{78, 88, 80},
{95, 90, 87}
};
// 访问元素:
int firstStudentMathGrade = grades[0][0]; // 访问第 0 行第 0 列(结果为 90)
System.out.println("第一位学生的数学成绩: " + firstStudentMathGrade);
int secondStudentScienceGrade = grades[1][1]; // 访问第 1 行第 1 列(结果为 88)
System.out.println("第二位学生的科学成绩: " + secondStudentScienceGrade);
// 修改元素:
grades[0][0] = 93; // 将第一位学生的数学成绩修改为 93
System.out.println("更新后的第一位学生数学成绩: " + grades[0][0]);5. 理解二维数组的长度属性
在二维数组中,.length 属性的行为略有不同:
数组名.length:返回行数(外部数组的长度)。数组名[行索引].length:返回该特定行中的列数(内部数组的长度)。
这在处理交错数组时特别有用。
int[][] exampleArray = {
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}
};
System.out.println("行数: " + exampleArray.length); // 输出: 3
System.out.println("第 0 行的长度: " + exampleArray[0].length); // 输出: 3
System.out.println("第 1 行的长度: " + exampleArray[1].length); // 输出: 2
System.out.println("第 2 行的长度: " + exampleArray[2].length); // 输出: 46. 实践案例演示
6.1 案例 1:存储简易游戏棋盘
想象一下创建一个井字棋(Tic-Tac-Toe)游戏。3x3 的网格是二维数组的完美应用场景。我们可以用字符来表示空位、'X' 和 'O'。
public class TicTacToeBoard {
public static void main(String[] args) {
// 声明并初始化一个 3x3 的字符数组作为井字棋盘
char[][] board = {
{' ', ' ', ' '}, // 第 0 行
{' ', ' ', ' '}, // 第 1 行
{' ', ' ', ' '} // 第 2 行
};
// 进行几次落子
board[0][0] = 'X'; // 玩家 X 在左上角落子
board[1][1] = 'O'; // 玩家 O 在中心落子
board[0][1] = 'X'; // 玩家 X 在上方中间落子
// 显示棋盘当前状态
System.out.println("当前井字棋盘状态:");
// 遍历行
for (int i = 0; i < board.length; i++) {
// 遍历当前行中的列
for (int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]); // 打印元素
if (j < board[i].length - 1) {
System.out.print(" | "); // 打印列分隔符
}
}
System.out.println(); // 换行
if (i < board.length - 1) {
System.out.println("---------"); // 打印行分隔符
}
}
}
}6.2 案例 2:存储销售数据
假设你需要存储不同产品的月度销售数据。二维数组可以轻松胜任:行表示产品,列表示月份(或季度)。
public class SalesData {
public static void main(String[] args) {
// 3 种产品在 4 个季度的销售数据
// 行:产品 (产品 A, 产品 B, 产品 C)
// 列:季度 (Q1, Q2, Q3, Q4)
double[][] quarterlySales = {
{1500.75, 1800.50, 2100.20, 1950.00}, // 产品 A 销售额
{1200.00, 1350.25, 1400.00, 1600.50}, // 产品 B 销售额
{800.00, 950.00, 1100.75, 1250.00} // 产品 C 销售额
};
// 计算产品 B 的总销售额
double totalSalesProductB = 0;
for (int i = 0; i < quarterlySales[1].length; i++) { // 遍历产品 B 行的每一列
totalSalesProductB += quarterlySales[1][i];
}
System.out.println("产品 B 的总销售额: $" + totalSalesProductB);
// 计算所有产品在第三季度 (Q3) 的总销售额
double totalSalesQ3 = 0;
for (int i = 0; i < quarterlySales.length; i++) { // 遍历每一行
totalSalesQ3 += quarterlySales[i][2]; // Q3 的索引是 2
}
System.out.println("所有产品在 Q3 的总销售额: $" + totalSalesQ3);
// 查找产品 A 的单季最高销售额
double highestSalesProductA = quarterlySales[0][0];
for (int i = 1; i < quarterlySales[0].length; i++) {
if (quarterlySales[0][i] > highestSalesProductA) {
highestSalesProductA = quarterlySales[0][i];
}
}
System.out.println("产品 A 的最高季度销售额: $" + highestSalesProductA);
}
}