繁体   English   中英

Java多维数组-为什么仅定义第一个大小就足够了?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM