Java数组操作——3.多维数组
Java多维数组
在Java中,数组不仅可以存储基本类型或对象的线性集合,还可以通过嵌套形成多维数组,以满足更复杂的数据存储需求。多维数组本质上是数组的数组,其中最常用的是二维数组,更高维度的数组(三维及以上)在特定场景下也有应用。
二维数组:数组的数组
二维数组是最常见的多维数组形式,可以理解为"数组的数组"——它的每个元素本身也是一个数组。这种结构非常适合表示表格、矩阵等二维数据。
二维数组的定义与初始化
定义二维数组的基本语法有多种形式:
- 完整初始化:直接指定每个子数组的元素
// 定义并初始化一个3行4列的二维数组
int[][] matrix = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
- 指定维度初始化:先指定外层数组长度,再初始化内层数组
// 定义一个3行的二维数组,每行长度后续指定
int[][] matrix = new int[3][];
matrix[0] = new int[]{1, 2, 3, 4}; // 第一行有4个元素
matrix[1] = new int[]{5, 6, 7}; // 第二行有3个元素
matrix[2] = new int[]{8, 9}; // 第三行有2个元素
- 指定行列初始化:同时指定外层和内层数组的长度
// 定义一个3行4列的二维数组,所有元素初始化为0
int[][] matrix = new int[3][4];
二维数组的内存结构
二维数组在内存中并非以连续的矩形存储,而是外层数组的每个元素指向一个独立的内层数组,这使得每行可以有不同的长度(称为"不规则数组")。
例如,对于以下二维数组:
int[][] irregular = {
{1, 2, 3, 4},
{5, 6},
{7, 8, 9}
};
访问二维数组元素
访问二维数组的元素需要使用两个索引:第一个索引指定外层数组的位置(行),第二个索引指定内层数组的位置(列),语法为array[row][col]。
public class Access2DArray {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 访问第二行第三列的元素(值为6)
int value = matrix[1][2];
System.out.println("matrix[1][2] = " + value); // 输出6
// 修改第一行第一列的元素
matrix[0][0] = 100;
System.out.println("修改后 matrix[0][0] = " + matrix[0][0]); // 输出100
}
}
注意:索引从0开始,访问时需确保不超出数组范围,否则会抛出
ArrayIndexOutOfBoundsException。
遍历二维数组
遍历二维数组需要使用嵌套循环,外层循环遍历行,内层循环遍历每行的元素。
- 使用普通for循环:适合需要索引的场景
public class Traverse2DWithFor {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 遍历二维数组
for (int i = 0; i < matrix.length; i++) { // 外层循环:行
for (int j = 0; j < matrix[i].length; j++) { // 内层循环:列
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 每行结束后换行
}
}
}
- 使用增强for循环:语法更简洁,无需关注索引
public class Traverse2DWithForEach {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 使用增强for循环遍历
for (int[] row : matrix) { // 遍历每行
for (int num : row) { // 遍历行中的每个元素
System.out.print(num + " ");
}
System.out.println();
}
}
}
- 使用Arrays.deepToString():快速打印二维数组内容
Java标准库的Arrays类提供了deepToString()方法,可以直接打印多维数组的内容:
import java.util.Arrays;
public class Print2DArray {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5},
{6}
};
// 直接打印多维数组
System.out.println(Arrays.deepToString(matrix));
// 输出:[[1, 2, 3], [4, 5], [6]]
}
}
三维及更高维数组
三维数组可以理解为"二维数组的数组",即外层数组的每个元素是一个二维数组。更高维度的数组以此类推,但在实际开发中很少使用三维以上的数组。
三维数组的定义与访问
import java.util.Arrays;
public class ThreeDimensionalArray {
public static void main(String[] args) {
// 定义一个三维数组
int[][][] cube = {
{
{1, 2},
{3, 4}
},
{
{5, 6},
{7, 8}
}
};
// 访问三维数组中的元素
int value = cube[1][0][1]; // 访问第二个二维数组的第一行第二列
System.out.println("cube[1][0][1] = " + value); // 输出6
// 打印三维数组
System.out.println(Arrays.deepToString(cube));
// 输出:[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
}
}
三维数组的内存结构比二维数组更复杂,但其访问方式遵循相同的逻辑:每多一维,就增加一个索引。
高维数组的适用场景
高维数组适用于表示具有多层嵌套结构的数据,例如:
- 三维数组:表示空间中的点(x, y, z坐标)、立方体数据等
- 四维数组:可能用于表示随时间变化的三维数据(如动态3D模型)
但需注意,维度越高,代码的可读性和维护性越差。在大多数情况下,使用类或集合框架(如List的嵌套)可以更清晰地表示复杂数据结构。
多维数组的实际应用案例
案例1:计算学生成绩的平均分
使用二维数组存储多名学生的多门成绩,计算所有成绩的平均分:
public class StudentScores {
public static void main(String[] args) {
// 二维数组:每行表示一名学生的各科成绩
int[][] scores = {
{82, 90, 91}, // 学生1:语文、数学、英语
{68, 72, 64}, // 学生2
{95, 91, 89}, // 学生3
{67, 52, 60}, // 学生4
{79, 81, 85} // 学生5
};
int total = 0;
int count = 0;
// 遍历所有成绩
for (int[] studentScores : scores) {
for (int score : studentScores) {
total += score;
count++;
}
}
// 计算平均分
double average = (double) total / count;
System.out.printf("所有学生的平均分:%.4f\n", average); // 输出77.7333
}
}
案例2:矩阵转置
将一个矩阵的行和列互换:
import java.util.Arrays;
public class MatrixTranspose {
public static void main(String[] args) {
// 定义一个3行2列的矩阵
int[][] matrix = {
{1, 2},
{3, 4},
{5, 6}
};
// 计算转置矩阵的维度(2行3列)
int rows = matrix.length;
int cols = matrix[0].length;
int[][] transposed = new int[cols][rows];
// 执行转置
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
transposed[j][i] = matrix[i][j];
}
}
System.out.println("原矩阵:" + Arrays.deepToString(matrix));
System.out.println("转置矩阵:" + Arrays.deepToString(transposed));
}
}
输出结果:
原矩阵:[[1, 2], [3, 4], [5, 6]]
转置矩阵:[[1, 3, 5], [2, 4, 6]]
注意事项
处理不规则数组:二维数组的每行长度可以不同,遍历时需使用
row.length获取每行的实际长度,避免索引越界。初始化注意事项:创建多维数组时,需确保外层数组初始化后再初始化内层数组,否则会导致
NullPointerException:
int[][] matrix = new int[3][];//只初始化了第一维,第二维需要单独初始化。
matrix[0][0] = 1; // 错误:matrix[0]未初始化,为null
正确做法:
int[][] matrix = new int[3][];
matrix[0] = new int[4]; // 先初始化内层数组
matrix[0][0] = 1; // 再访问元素
总结
- 二维数组是"数组的数组",每行可以有不同长度,因此第二维也需要初始化再访问
- 访问元素需使用多个索引,如
array[row][col] - 遍历多维数组需使用嵌套循环
Arrays.deepToString()可快速打印多维数组内容
Java数组操作——3.多维数组的更多相关文章
- 廖雪峰Java1-4数组操作-4多维数组
二维数组 二维数组就是元素为数组的数组 二维数组每个数组的长度不要求一样.比如 int[][] = { { 1, 2 }, { 3, 4, 5 }, { 6, 7, 8, 9 } } int[][] ...
- 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作
二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...
- Java中如何获取多维数组的长度
在程序处理中遍历数组是一种很常见的操作,但遍历数组时,我们需要知道数组各维度的长度(一维数组除外,for each 可以遍历),下面举例说明如何求多维数组的长度. 一维 : int [] array ...
- java怎么定义一个二维数组?
java中使用 [][] 来定义二维数组 定义数组时也可同时初始化下面是一些例子float[][] numthree; //定义一个float类型的2维数组numthree=new float[5][ ...
- java基础知识点补充---二维数组
#java基础知识点补充---二维数组 首先定义一个二维数组 int[][] ns={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }; 实现遍 ...
- java笔记11之二维数组
格式1: 二维数组:就是元素为一维数组的一个数组 数据类型[][] 数组名 = new 数组类型[m][n] 其中m为行 n为列 注意: A:以下格式也可以表示二维数组 a:数据 ...
- Java实验项目二——二维数组实现九九乘法表
Program:打印乘法口诀表 (1)编写一个方法,参数(二维数组),完成将二维数组中的数据按照行列显示的工作. (2)编写一个测试方法,给出99乘法表,放入到二维数组中,调用(1)中的方法,显示乘法 ...
- C语言数组:C语言数组定义、二维数组、动态数组、字符串数组
1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...
- php数组操作集锦- 掌握了数组操作, 也就掌握了php
参考下面的文章, 是很好的: http://www.cnblogs.com/staven/p/5142515.html http://pcwanli.blog.163.com/blog/static/ ...
- [zt]C++二维数组讲解、二维数组的声明和初始化
定义: int *pia = new int[10]; // array of 10 uninitialized ints 此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向 ...
随机推荐
- Guava中的常见集合操作用法
本文主要介绍Guava中几种处理字符串和Map的方法,包括Joiner(连接).FluentIterable(过滤.转换集合)和Splitter(分割).本文基于Java 8进行测试,Guava 版本 ...
- 在MySQL数据库中保存布尔型数据
在存储数据时,经常会用到"是"."否"或者"有"."无"这种数据,这种时候就要应用布尔型这种数据类型了.那如何在M ...
- MCN机构如何用板栗看板打造内容工厂式效率?从短视频脚本到多平台分发的全流程协作管理
一.内容为王的时代,MCN却陷入"人海混战" 在抖音.小红书.B站全面爆发的当下,MCN机构已成为内容产业链的核心角色.脚本创作.拍摄剪辑.品牌对接.渠道分发--每个流程都离不开高 ...
- 官宣!Taier1.3新版本正式发布,新鲜功能抢先体验
2022年11月7日,Taier1.3版本正式发布! Taier 是一个大数据分布式可视化的DAG任务调度系统,旨在降低ETL开发成本.提高大数据平台稳定性,大数据开发人员可以在 Taier 直接进行 ...
- GAMES101作业1
声明:使用的是vs2022版,以下内容如有问题,感谢各位大佬指正! 作业要求: 作业目的:模拟一个基于 CPU 的光栅化渲染器的简化版本 我们需要做的: 在main.cpp中修改 Eigen::Mat ...
- HyperWorks批处理网格的类型设置
网格类型设置(Configuration Tab) HyperWorks中BatchMesher 的 Configuration Tab 向用户提供了网格方案类型(Mesh Type)的选择.一个典型 ...
- 以接口肢解bean factory,源码没那么神秘
本来昨天在看 spring frame的八股, 看到了IOC部分,但是实在看不懂是什么东西,讲是讲源码部分,但又不完全讲,我想着那我要不自己看一下源码 这是我画的Bean Factory的大致关系图 ...
- 【译】更优的模型,更智能的设置:Claude Sonnet 4、GPT-4.1 及 Visual Studio 中的更多控制
我们很高兴宣布 Visual Studio 中 Copilot 体验的重大升级,包括更智能的默认模型.更多选择以及更简单的用量管理方式. 更智能的默认模型 Visual Studio 中的 Copil ...
- [原创]《C#高级GDI+实战:从零开发一个流程图》第05章:有锯齿?拖动闪烁?优化!优化!
一.前言 前面的课程我们实现了矩形.圆形的拖动,以及不同形状间的连线,在实现的过程中,很多读者都发现并提出来了存在显示质量差有锯齿.拖动不流畅还闪烁等问题,作为承上启下的一节课程,我们本节就来看一上如 ...
- C++ stack容器 总结
-----------------------------------stack 容器 stack是一种先进后出(first in last out,FILO)的数据结构,他只有一个出口,stack只 ...