[英]Java multidimensional array - Why is only defining the first size enough?
带有以下Java示例:
int[] array1 = new int[]; // Incorrect, since no size is given
int[] array2 = new int[2]; // Correct
int[][][] array3 = new int[][][]; // Incorrect, since no size is given
int[][][] array4 = new int[2][2][2]; // Correct
int[][][] array5 = new int[2][][]; // Correct (why is this correct?)
所以,我的问题是,为什么仅分配多维数组的第一个大小就足够了? 我以为您总是必须为多维数组的每个单独的数组部分分配大小,但是今天我发现array5
也是Java的正确方法。 现在我只是想知道为什么。 有人可以举例说明为什么它适用于多维数组和/或其背后的原因吗?
另外,我认为以下内容同样适用:
int[][][] array6 = new int[][2][]; // Incorrect
int[][][] array7 = new int[][][2]; // Incorrect
int[][][] array8 = new int[][2][2]; // Incorrect
int[][][] array9 = new int[2][2][]; // Correct
int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?)
我现在有些困惑,如果有人知道,我想澄清一下。
编辑/半解决方案:
好的,我发现了为什么第一部分起作用:
int[][] array = new int[2][];
array[0] = new int[5];
array[1] = new int[3];
// So now I have an array with the following options within the array-index bounds:
// [0][0]; [0][1]; [0][2]; [0][3]; [0][4]; [1][0]; [1][1]; [1][2]
// It basically means I can have different sized inner arrays
唯一需要回答的是:
int[][][] array10 = new int[2][][2]; // Incorrect?? (Or is this correct?)
是否有效。
从简单开始:二维数组是数组的数组。 Java中的数组是对象。 因此,仅定义第一个大小会创建给定大小的数组,该数组可以存储其他数组,但此时这些数组仍为空。 因此,在使用它之前,您需要调用array1[0] = new int[5]
,否则会得到NullPointerException。 对于更高维的数组,这适用。
从理论上讲,所有“内部”数组实际上都可以具有不同的长度。 因此,您可以编写如下内容: array1[0] = new int[1]; array1[1] = new int[4];
array1[0] = new int[1]; array1[1] = new int[4];
。
关于您的最后一个问题:这是无效的,Java编译器会说类似“在空维之后不能指定数组维”的内容。 这是由于以下事实:未指定第二级,因此是第一级数组中的空对象,因此,不能在这些空数组上指定维。
因为您没有定义多维数组。 您实际上定义的是int
数组的数组。 例如,您可以执行以下操作:
int[][] array1 = new int[5][];
for(int i = 0; i < 5; i++){
array1[i] = new int[i];
}
这导致锯齿状数组。
因此, int[2][]
定义了一个数组数组。 int[2][2]
定义了一个数组数组,并且还定义了所有内部数组。 int[][2]
试图定义所有内部数组,而没有放入它们的任何内容,因此失败。
另一种思考的方式是,您以后可以更改存储在最外层数组中的引用(即更改一行值),但是不能沿另一条轴进行修改(更改列)。 所以这是有效的:
int[][] arr = new int[2][2];
arr[0] = new int[3];
虽然不是:
int[][] arr = new int[2][2];
arr[][0] = new int[3];
这是因为
int[][][] array = new int[n][m][p];
等效于创建n维数组,然后用对 m维数组的n个实例的引用填充它,然后用对 m维数组的m个实例的引用填充该数组。
如果并非所有维都存在,则说明您已部分初始化了数组。
int[][][] array5 = new int[2][][]; // Correct (why is this correct)
编写此代码可以实例化一个int [] []数组。 在内存中,它是对int [] []的引用的数组。 您不需要知道int [] []的大小,因为它只是一个参考,并且每个大小可能都不同。
以这种方式查看内存:
array5:[length a ref, length of a ref]
然后实例化subArray0:
... ,subArray0[ length of a ref, length of a ref], ...
并影响子数组到主数组
array5:[refToSubArray0, length of a ref],
但是无论子数组的长度如何,您都只需将引用的长度保存在内存中即可将子数组存储在其中,因为它存储在其他位置。
int[][][] array10 = new int[2][][2]; // Correct?? (Is this correct?)
这是不正确的。 我相信当你这样做
new int[2][2][2]
您在内存中分配:
array[ref0,ref1], sub0[ref00,ref01], sub1[ref10,ref11], sub00[int000, int001], sub00[int000, int001], sub01[int010, int011], sub10[int100, int101], sub11[int110, int111] ...
如果跳过数组大小,则它无法为第三个子数组分配内存,因为它不知道将实例化多少个子数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.