为什么Java 2D阵列初始化违背了直觉?

时间:2022-02-13 21:35:16

Why do multidimensional arrays behave opposite from what you would expect when creating them? An int[][] array means that I should have an array of arrays of ints. I would read it backwards starting from the rightmost brackets: ((int)[])[].

为什么多维数组的行为与创建它们时的预期相反? int [] []数组意味着我应该有一个int数组。我会从最右边的括号开始向后读它:((int)[])[]。

And I would expect the following code,

我希望以下代码,

int[][] grid = new int[][3];
// ...Proceed to fill nested arrays

to create a 3-element array of int arrays. But it produces a compiler error. However this,

创建一个3元素的int数组数组。但它会产生编译错误。不过这个,

int[][] grid = new int[3][];

does not. The first example makes sense to me, because it seems like I am creating a 3-element array of null int array references. But the second example doesn't make sense to me, since it seems as though the actual array of int arrays has no set size, but the 'nested' arrays are still initialized with a size of 3. Why is this?

才不是。第一个例子对我有意义,因为我好像在创建一个3元素的null int数组引用数组。但是第二个例子对我来说没有意义,因为似乎实际的int数组数组没有设置大小,但'嵌套'数组仍然初始化为3。为什么这样?

4 个解决方案

#1


2  

Your intuition is reversed. The declaration

你的直觉是相反的。声明

int [][] a;

just creates a variable that's a reference to an array of references to arrays of ints. An allocation

只创建一个变量,该变量是对int数组的引用数组的引用。分配

new int [3][2];

creates an array of 3 references. Each reference is to an array of 2 elements. The allocation

创建一个包含3个引用的数组。每个引用都是一个包含2个元素的数组。分配

new int [3][];

still makes sense. It still creates an array of 3 references, but the references are null.

仍然有道理。它仍然创建一个包含3个引用的数组,但引用为null。

On the other hand, the allocation

另一方面,分配

new int [][3];

doesn't make sense because it doesn't specify how many references are to be allocated. Knowing how many elements would be in the referenced arrays isn't of any use.

没有意义,因为它没有指定要分配多少引用。知道引用数组中有多少元素没有任何用处。

Note that to get at a[i][j], Java uses the ith reference to get the address of the corresponding array, then gets the jth element within that array.

注意,为了获得[i] [j],Java使用第i个引用来获取相应数组的地址,然后获取该数组中的第j个元素。

This is in contrast to C or C++, where a declaration (not allocation)

这与C或C ++形成对比,其中声明(不是分配)

int a[][3];

is possible. This creates a single pointer (with undefined value) that refers to a single block of memory that's treated as a sequence of rows each having 3 elements. Here, there are no references. Elements are accessed with arithmetic: a[i][j] is the integer with offset 3*i+j.

是可能的。这将创建一个单指针(具有未定义的值),该指针指向单个内存块,该内存块被视为每个具有3个元素的行序列。这里没有参考。使用算术访问元素:a [i] [j]是偏移3 * i + j的整数。

#2


1  

You are probably thinking a bit too much in terms of C.

你可能在C方面有点想太多了。

In java, there are no true 2-dimensional arrays. There are only one-dimensional arrays, and to create a two-dimensional array you have to create a one-dimensional array of one-dimensional arrays. (Incidentally, this means that each row can be of different length. But that's besides the point.)

在java中,没有真正的二维数组。只有一维数组,要创建二维数组,必须创建一维数组的一维数组。 (顺便说一句,这意味着每行可以有不同的长度。但除此之外。)

So when you declare an array in C you have to specify the size of a row, so that the compiler can figure out how far apart in memory each row is. The number of rows does not really matter as far as the type is concerned, it is a run-time consideration.

因此,当您在C中声明一个数组时,您必须指定行的大小,以便编译器可以计算每行在内存中的距离。就类型而言,行数并不重要,它是运行时考虑因素。

But when you declare an array in Java you have to begin by specifying the size of the primary array, (essentially, how many rows you have,) and then allocate each sub-array (each row.)

但是当你在Java中声明一个数组时,你必须首先指定主数组的大小(基本上,你有多少行),然后分配每个子数组(每行)。

Edit:

Essentially, int[][] a = new int[][5] in java would mean "allocate an array of int[] of unknown size (impossible) where each int[] will contain 5 elements (impossible)". Instead, you have to say int[][] a = new int[5][] which means "allocate an array of 5 pointers to int[] and I am going to be allocating each member int[] later."

基本上,java中的int [] [] a = new int [] [5]意味着“分配一个未知大小的int []数组(不可能),其中每个int []将包含5个元素(不可能)”。相反,你必须说int [] [] a = new int [5] []这意味着“分配一个包含5个指向int []的数组,我将在稍后分配每个成员int []。”

#3


0  

Your first interpretation is wrong.
When you do int[][] grid = new int[][3]; it has no meaning but : create 0(or null) arrays of 3 columns it's impossible (You made no memory place for the 3 arrays so you can't declare them). The second one means : Create 3 arrays pointing to nothing (empty). that's possible since you can append elements later. I hope this was as simplified as possible so you can understand it.

你的第一个解释是错误的。当你做int [] [] grid = new int [] [3];它没有意义但是:创建3列的0(或null)数组是不可能的(你没有为3个数组设置内存,所以你不能声明它们)。第二个意思是:创建3个指向空的数组(空)。这是可能的,因为您可以稍后追加元素。我希望这是尽可能简化的,这样你才能理解它。

#4


0  

We usually tend to read code from left to right.

我们通常倾向于从左到右阅读代码。

A representation like int[ [] ] could help because then you see the nesting, however it would not be suitable for those size statements you showed. Thus you need to decide for either your interpretation or the one they choosed.

类似int [[]]的表示可能会有所帮助,因为您会看到嵌套,但它不适合您展示的那些大小的语句。因此,您需要决定您的解释或他们选择的解释。

As I already said, we tend to read from left to right, so when writing new int[3][]; most people expect that the left brackets represent the outer-array and the right the inner-array.

正如我已经说过的,我们倾向于从左到右阅读,所以在编写新的int [3] []时;大多数人都希望左括号代表外部数组,右边代表内部数组。

Take a look at the equation (x * (y + z)), the outer brackets are read before the inner ones.

看看方程式(x *(y + z)),外部括号在内部括号之前读取。

It kind of reminds me of prefix notation where you would write * x (+ y z) for the above equation.

它让我想起了前缀符号,你可以在上面的等式中写* x(+ y z)。

#1


2  

Your intuition is reversed. The declaration

你的直觉是相反的。声明

int [][] a;

just creates a variable that's a reference to an array of references to arrays of ints. An allocation

只创建一个变量,该变量是对int数组的引用数组的引用。分配

new int [3][2];

creates an array of 3 references. Each reference is to an array of 2 elements. The allocation

创建一个包含3个引用的数组。每个引用都是一个包含2个元素的数组。分配

new int [3][];

still makes sense. It still creates an array of 3 references, but the references are null.

仍然有道理。它仍然创建一个包含3个引用的数组,但引用为null。

On the other hand, the allocation

另一方面,分配

new int [][3];

doesn't make sense because it doesn't specify how many references are to be allocated. Knowing how many elements would be in the referenced arrays isn't of any use.

没有意义,因为它没有指定要分配多少引用。知道引用数组中有多少元素没有任何用处。

Note that to get at a[i][j], Java uses the ith reference to get the address of the corresponding array, then gets the jth element within that array.

注意,为了获得[i] [j],Java使用第i个引用来获取相应数组的地址,然后获取该数组中的第j个元素。

This is in contrast to C or C++, where a declaration (not allocation)

这与C或C ++形成对比,其中声明(不是分配)

int a[][3];

is possible. This creates a single pointer (with undefined value) that refers to a single block of memory that's treated as a sequence of rows each having 3 elements. Here, there are no references. Elements are accessed with arithmetic: a[i][j] is the integer with offset 3*i+j.

是可能的。这将创建一个单指针(具有未定义的值),该指针指向单个内存块,该内存块被视为每个具有3个元素的行序列。这里没有参考。使用算术访问元素:a [i] [j]是偏移3 * i + j的整数。

#2


1  

You are probably thinking a bit too much in terms of C.

你可能在C方面有点想太多了。

In java, there are no true 2-dimensional arrays. There are only one-dimensional arrays, and to create a two-dimensional array you have to create a one-dimensional array of one-dimensional arrays. (Incidentally, this means that each row can be of different length. But that's besides the point.)

在java中,没有真正的二维数组。只有一维数组,要创建二维数组,必须创建一维数组的一维数组。 (顺便说一句,这意味着每行可以有不同的长度。但除此之外。)

So when you declare an array in C you have to specify the size of a row, so that the compiler can figure out how far apart in memory each row is. The number of rows does not really matter as far as the type is concerned, it is a run-time consideration.

因此,当您在C中声明一个数组时,您必须指定行的大小,以便编译器可以计算每行在内存中的距离。就类型而言,行数并不重要,它是运行时考虑因素。

But when you declare an array in Java you have to begin by specifying the size of the primary array, (essentially, how many rows you have,) and then allocate each sub-array (each row.)

但是当你在Java中声明一个数组时,你必须首先指定主数组的大小(基本上,你有多少行),然后分配每个子数组(每行)。

Edit:

Essentially, int[][] a = new int[][5] in java would mean "allocate an array of int[] of unknown size (impossible) where each int[] will contain 5 elements (impossible)". Instead, you have to say int[][] a = new int[5][] which means "allocate an array of 5 pointers to int[] and I am going to be allocating each member int[] later."

基本上,java中的int [] [] a = new int [] [5]意味着“分配一个未知大小的int []数组(不可能),其中每个int []将包含5个元素(不可能)”。相反,你必须说int [] [] a = new int [5] []这意味着“分配一个包含5个指向int []的数组,我将在稍后分配每个成员int []。”

#3


0  

Your first interpretation is wrong.
When you do int[][] grid = new int[][3]; it has no meaning but : create 0(or null) arrays of 3 columns it's impossible (You made no memory place for the 3 arrays so you can't declare them). The second one means : Create 3 arrays pointing to nothing (empty). that's possible since you can append elements later. I hope this was as simplified as possible so you can understand it.

你的第一个解释是错误的。当你做int [] [] grid = new int [] [3];它没有意义但是:创建3列的0(或null)数组是不可能的(你没有为3个数组设置内存,所以你不能声明它们)。第二个意思是:创建3个指向空的数组(空)。这是可能的,因为您可以稍后追加元素。我希望这是尽可能简化的,这样你才能理解它。

#4


0  

We usually tend to read code from left to right.

我们通常倾向于从左到右阅读代码。

A representation like int[ [] ] could help because then you see the nesting, however it would not be suitable for those size statements you showed. Thus you need to decide for either your interpretation or the one they choosed.

类似int [[]]的表示可能会有所帮助,因为您会看到嵌套,但它不适合您展示的那些大小的语句。因此,您需要决定您的解释或他们选择的解释。

As I already said, we tend to read from left to right, so when writing new int[3][]; most people expect that the left brackets represent the outer-array and the right the inner-array.

正如我已经说过的,我们倾向于从左到右阅读,所以在编写新的int [3] []时;大多数人都希望左括号代表外部数组,右边代表内部数组。

Take a look at the equation (x * (y + z)), the outer brackets are read before the inner ones.

看看方程式(x *(y + z)),外部括号在内部括号之前读取。

It kind of reminds me of prefix notation where you would write * x (+ y z) for the above equation.

它让我想起了前缀符号,你可以在上面的等式中写* x(+ y z)。