1.7 Java到底有没有多维数组?
Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能。
Java 语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。
定义数组类型的语法type[] arrName
;是典型的一维数组的定义语法,其中 type 是数组元素的类型。如果希望数组元素也是一个引用,而且是指向 int 数组的引用,则可以把 type 具体成 int[](前面已经指出,int[] 就是一种类型,int[] 类型的用法与普通类型并无任何区别),那么上面定义数组的语法就是int[][] arrName。
如果把 int 这个类型扩大到 Java 的所有类型(不包括数组类型),则出现了定义二维数组的语法:
type[][] arrName;
Java 语言采用上面的语法格式来定义二维数组,但它的实质还是一维数组,只是其数组元素也是引用,数组元素里保存的引用指向一维数组。
接着对这个“二维数组”执行初始化,同样可以把这个数组当成一维数组来初始化,把这个“二维数组”当成一个一维数组,其元素的类型是 type[] 类型,则可以采用如下语法进行初始化:
arrName = new type[length][]
上面的初始化语法相当于初始化了一个一维数组,这一维数组的长度是 length。同样,因为这个一维数组的数组元素是引用类型(数组类型)的,所以系统为每个数组元素都分配初始值:null。
这个二维数组实际上完全可以当成一维数组使用:使用new type[length]
初始化一维数组后,相当于定义了 length 个 type 类型的变量。类似的,使用new type[length][]
初始化这个数组后,相当于定义了 length 个 type[] 类型的变量。当然,这些 type[] 类型的变量都是数组类型,因此必须再次初始化这些数组。
下面程序示范了如何把二维数组当成一维数组处理。
public class TwoDimensionTest {public static void main(String[] args) {// 定义一个二维数组int[][] a;// 把a当成一维数组进行初始化,初始化a是一个长度为4的数组// a数组的数组元素又是引用类型a = new int[4][];// 把a数组当成一维数组,遍历a数组的每个数组元素for (int i = 0, len = a.length; i < len; i++) {System.out.println(a[i]); // 输出 null null null null}// 初始化a数组的第一个元素a[0] = new int[2];// 访问a数组的第一个元素所指数组的第二个元素a[0][1] = 6;// a数组的第一个元素是一个一维数组,遍历这个一维数组for (int i = 0, len = a[0].length; i < len; i++) {System.out.println(a[0][i]); // 输出 0 6}}
}
上面程序中粗体字代码部分把 a 这个二维数组当成一维数组处理,只是每个数组元素都是 null,所以看到输出结果都是 null。下面结合示意图来说明这个程序的执行过程。
程序中代码int[][] a
;将在栈内存中定义一个引用变量,这个变量并未指向任何有效的内存空间,此时的堆内存中还未为这行代码分配任何存储区。
程序中代码a = new int[4][];
对 a 数组执行初始化,这行代码让 a 变量指向一块长度为 4 的数组内存,这个长度为 4 的数组里每个数组元素都是引用类型(数组类型),系统为这些数组元素分配默认的初始值:null。此时 a 数组在内存中的存储示意图如图 1 所示。
从图 1 来看,虽然声明 a 是一个二维数组,但这里丝毫看不出它是一个二维数组的样子,完全是一维数组的样子。这个一维数组的长度是 4,只是这 4 个数组元素都是引用类型,它们的默认值是 null。所以程序中可以把 a 数组当成一维数组处理,依次遍历 a 数组的每个元素,将看到每个数组元素的值都是 null。
由于 a 数组的元素必须是 int[] 数组,所以接下来的程序对 a[0] 元素执行初始化,也就是让图 1 右边堆内存中的第一个数组元素指向一个有效的数组内存,指向一个长度为 2 的 int 数组。因为程序采用动态初始化 a[0] 数组,因此系统将为 a[0] 所引用数组的每个元素分配默认的初始值:0,然后程序显式为 a[0] 数组的第二个元素赋值为 6。此时在内存中的存储示意图如图 2 所示。
图 2 中灰色覆盖的数组元素就是程序显式指定的数组元素值。TwoDimensionTest.java 接着迭代输出 a[0] 数组的每个数组元素,将看到输出 0 和 6。
是否可以让图 2 中灰色覆盖的数组元素再次指向另一个数组?这样不就可以扩展成三维数组,甚至扩展成更多维的数组嘛?
不能!至少在这个程序中不能。因为 Java 是强类型语言,当定义 a 数组时,已经确定了 a 数组的数组元素是 int[] 类型,则 a[0] 数组的数组元素只能是 int 类型,所以灰色覆盖的数组元素只能存储 int 类型的变量。对于其他弱类型语言,例如 JavaScript 和 Ruby 等,确实可以把一维数组无限扩展,扩展成二维数组、三维数组…,如果想在 Java 语言中实现这种可无限扩展的数组,则可以定义一个 Object[] 类型的数组,这个数组的元素是 Object 类型,因此可以再次指向一个 Object[] 类型的数组,这样就可以从一维数组扩展到二维数组、三维数组…
从上面程序中可以看出,初始化多维数组时,可以只指定最左边维的大小;当然,也可以一次指定每一维的大小。例如下面代码:
// 同时初始化二维数组的两个维数
int[][] b = new int[3][4];
上面代码将定义一个 b 数组变量,这个数组变量指向一个长度为 3 的数组,这个数组的每个数组元素又是一个数组类型,它们各指向对应的长度为 4 的 int[] 数组,每个数组元素的值为 0。这行代码执行后在内存中的存储示意图如图 3 所示。
还可以使用静态初始化方式来初始化二维数组。使用静态初始化方式来初始化二维数组时,二维数组的每个数组元素都是一维数组,因此必须指定多个一维数组作为二维数组的初始化值。如下代码所示:
// 使用静态初始化语法来初始化一个二维数组
String[][] str1 = new String[][]{new String[3], new String[]{"hello"}};
// 使用简化的静态初始化语法来初始化二维数组
String[][] str2 = {new String[3], new String [] {"hello"}};
上面代码执行后内存中的存储示意图如图 4 所示。
通过上面讲解可以得到一个结论:二维数组是一维数组,其数组元素是一维数组。三维数组也是一维数组,其数组元素是二维数组…… 从这个角度来看,Java 语言里没有多维数组。
1.7 Java到底有没有多维数组?相关推荐
- int数组初始化_Java中到底有没有多维数组
Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能. Java 语言里的数组类型是引用类型,因此数组变 ...
- 韩顺平循序渐进学java 第19讲 多维数组
19.1 二维数组 高维数组在工作中用到的不多,所以只介绍二维数组. 1.定义 语法:类型 数组名[][]=new 类型[大小][大小] 比如:int a[][]=new int[2][3] 2.分析 ...
- Java学习---面向对象与多维数组
多维数组 定义: n维数组就是元素为n-1维数组的数组 int[] 数组名 int[][] 数组名 int 数组名 [] int[] 数组名[] 初始化: 1 . 数据类型[][] 数组名 = new ...
- 小白自学笔记——JAVA基础 3.2 多维数组
名词解释 Java 语言里提供了支持多维数组的语法. 如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel中的表格一样. 对于二维数组的理解,我们可以看成是一维数组a ...
- java练习day06-Debug-进制-二维数组-杨辉三角
Day06 Debug Debug概述: Debug是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序. Debug操作流程 Debug调试,又被 ...
- java中控制台输入二维数组(Scanner类总结)
由于牛客和LeetCode上的题目不用自己写输入,但实际笔试中都需要从输入开始写,遇到需要从控制台输入二维数组的情况,故对java中的Scanner类作整理和总结. 通过 Scanner 类能获取用户 ...
- java中用length求二维数组的长度
今天刷题的时候碰到二维数组长度的问题,直接敲代码验证~ 用事实说话: 说明length求得的是二维数组的行数,即data[i][j]中的i 但如果要求二维数组的列数呢?很简单,用data[0].len ...
- Java基础动态初始化二维数组
直接上代码: //动态初始化二维数组 public class ArrayTest09 {public static void main(String[] args) {//定义一个二维数组并动态初始 ...
- java实现n阶二维数组(n×n)的顺时针旋转90°、180°、270°
一.首先第一步是要初始化一个你任意的n阶方阵,初始化的语句参考如下: int arr[][] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 二 ...
最新文章
- python更新pip失败-解决Python pip 自动更新升级失败的问题
- Bit-Z携手Bit-MY落户马来西亚 已获得经营牌照
- Bootstrap3免费单页面模板-Shuffle
- oracle 删除表中重复记录,并保留一条
- MSSQL · 最佳实践 · 利用文件组实现冷热数据隔离备份方案
- python123第6周答案_python123 测验6: 组合数据类型 (第6周)
- 滴滴升级“极速拼车”:未拼成可享折扣 拼成更便宜
- SAP License:最近的FICO面试题目
- SQL Server中自定义函数:用指定的分隔符号分割字符串
- 计算机无法识别建行网银盾,建行网银盾无法识别怎么办 几招办法教你轻松解决...
- 教程 | 如何用思维导图做自我介绍
- html之响应式(自适应)网页设计
- 哈罗数据分析(SQL)笔试
- 使用C语言教你轻松学会Cantor表
- Linux下execl函数与execlp函数的具体详细用法
- MySql的下载和安装
- ORAN专题系列-16:5G O-RAN FrontHaul前传接口的网络配置管理协议netconf
- 【Macbook 软件分享|使用技巧】干货
- 2.3 PPT :用logo设计封面
- kernel32 ntdll