使用以下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?)
我现在有点困惑,如果有人知道的话,我想澄清一下。
EDIT / SEMI-SOLUTION:
好的,我发现了为什么第一部分有效:
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?)
是否有效。
答案 0 :(得分:3)
开始简单:二维数组是一个数组数组。 Java中的数组是对象。只定义第一个大小因此会创建一个给定大小的数组,它可以存储其他数组,但此时仍为空。所以在使用它之前,你需要调用类似array1[0] = new int[5]
的东西,否则你会得到一个NullPointerException。
对于更多维数组,这相应适用。
理论上,所有"内部"实际上,数组可以有不同的长度。所以你可以这样写:array1[0] = new int[1]; array1[1] = new int[4];
。
关于你的上一个问题: 这是无效的,Java编译器会说类似"无法在空维度后指定数组维度"。这是因为未指定第二级,因此在第一级数组中是空对象,因此,不能在这些空数组上指定维度。
答案 1 :(得分:1)
因为您没有定义多维数组。你实际定义的是int
s的数组数组。例如,你可以这样做:
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];
答案 2 :(得分:0)
这是因为
int[][][] array = new int[n][m][p];
相当于创建n维数组,然后用引用填充到m维数组的n个实例,然后用对p维数组的m个实例的引用填充该数组。 / p>
当并非所有尺寸都存在时,您已经部分初始化了数组。
答案 3 :(得分:0)
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],
但无论子数组的长度如何,您只需要在内存中保存引用的长度以存储subArray,因为它存储在其他地方。
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] ...
如果跳过数组大小,它就不能为第三个子数组分配内存,因为它不知道将实例化多少个子数组。