二维数组
在一维数组的介绍当中曾说,数组中可以储存任何同类型的元素,那么这个元素是不是可以也是数组呢?答案是可以,即在数组之中储存数组元素。这种情况就是多维数组,当一个数组中的元素是数组时叫做二维数组,当这个数组中的数组元素的元素仍然是数组时叫做三位数组,依次类推可以得到n维数组。不过通常的使用中一般只用到二位数组。
二维数组的定义与一位数组的定义相似,可以通过语句:
1、数据类型 [ ] [ ] 数组名称 = new [一维数组的长度] [ ];
2、数据类型 数组名称 [ ] [ ] = new [一维数组的长度] [ ];
3、数据类型 [ ] [ ] = new 数据类型 [ ] [ ]{数组1,数组2,数组3,……};
4、数据类型 [ ] [ ] ={ 数组1,数组2,数组3,……};
四个语句来定义,同样在这四个数组中,第2个语句是第一个语句的变体,第3个语句和第4个语句当中需要注意输入的是数组元素即可,并且这里要注意的是,在第1个语句和第2个语句中“一维数组的长度”是必不可少的,但是第二个[ ]中是不能添加长度的。
对于二位数组的访问,可以访问其中的某一个数组,也可访问到具体单个元素,比如在二维数组中arr[0]表示的是一个数组,当进行输出打印时,结果是一个一维数组,而arr[0][0]表示的是在二维数组中的第一行的第一个元素。掌握了这个访问规则,就可以对二维数组中的元素进行遍历,可以直接进行遍历,也可以采用嵌套循环来遍历。比如下面的这个程序所示:
package cn.luoyusanshu.array;
import java.util.Arrays;
public class Test05 {
public static void main(String[] args) {
//第1个语句创建二维数组
int[][] arr01 = new int[3][];
arr01[0] =new int[] {1,5,6};
arr01[1] = new int[] {1,5,8,7};
arr01[2] = new int[] {4,9,66};
//第2个语句创建二位数组
int arr02[][]=new int[3][];
arr02[0] = new int[]{1,6,8,9};
arr02[1] = new int[]{8,69,8,9};
arr02[2] = new int[]{5,6,8,79};
//第3个语句创建二维数组
int[][] arr03 = new int[][]{{1,2,9},arr02[1],arr02[2]};
//第4个语句创建二维数组
int[][] arr04 = {{0,2,5},{3,6,9,6},{4,8,11,22}};
//访问二维数组中的元素
System.out.println("二维数组arr0的第一个数组元素为:"+Arrays.toString(arr01[0]));
System.out.println("二维数组arr01的第一个元素为:"+arr01[0][0]);
System.out.println("二维数组arr01的长度为:"+arr01.length);
System.out.println("二维数组arr01的第一个数组元素的长度为:"+arr01[0].length);
}
}
数组的内存图解
在java中将内存分为栈、堆、方法区三大块,其中方法区用来储存可运行的class文件,包括方法、静态成员、常量等;栈是方法运行时的内存,也就说在运行方法时才会调用此处内存,在栈中开辟空间时是连续开辟的,和电影胶带有些相似,因此运行时开辟的空间叫这个方法在栈中对应的栈帧。栈的特点是“先进后出”,比如main方法是最先开辟栈帧的方法,但是它却是最后一个退出栈空间的方法。推内存够用于储存对象以及数组。数组在推内存中被储存时用来接收数组的变量(如arr)接收的是数组所在内存的地址值,而不是数组中元素的实际值,因此数组是引类型,如果要对一个数组进行初始化,要用null关键字进行赋值。
接下来用一个程序来分析二维数组在内存中的储存进行分析,用以加深对数组也是对象的理解。
package cn.luoyusanshu.array;
public class Test08 {
public static void main(String[] args) {
int[][] arr = new int[3][];
arr[0]=new int[2];
arr[1]=new int[3];
arr[2]=new int[2];
}
}
在这个程序的内存分析中只用到了 栈内存和堆内存两块,程序开始时,从main方法开始运行,创建数组之前先在main方法的栈帧中创建了一个变量,由于未进行赋值,它的值为默认值,因为创建的是数组,所以它的默认值为null。随后遇到关键字new,于是想堆内存申请开辟空间,假设这个空间的地址为0x0011,这时会按照创建的数组大小在推内存中开辟相应的空间,并将空间的地址传给arr变量。但由于创建数组时并未进行赋值操作,为默认初始化,所以数组元素的值为默认值,又因为二维数组中的元素为数组类型,因此此时的默认值为null。
接下来对数组中的元素进行赋值操作,在下面的三行代码都采用了new关键字,因此会向推内存申请开辟三个空间,与这三个空间对应的地址分别为 0x0021、0x0031、0x0022。由于创建的为int类型的数组对象,并且未进行赋值操作,因此元素的值为默认值0。同时开辟的这三个空间的地址会返回给对应的一位数组对应的元素,如下图所示。