-1

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

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,

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?

name
  • 362
  • 2
  • 12
  • 3
    It sounds like you're asking why it doesn't make sense which none of us can answer other than to say your interpretation of the syntax isn't what you get. It makes sense to me ;) – ChiefTwoPencils Jul 29 '17 at 01:20
  • @ChiefTwoPencils Then explain why it makes sense to you please. – name Jul 29 '17 at 01:22
  • 2
    Because the designers didn't use your intuition. They used their own. The question here is really why you have the intuition you have, and only you can answer that. – user207421 Jul 29 '17 at 01:22
  • *An `int[][]` array means that I should have an array of arrays of ints.* **Correct**! It does. *I would read it backwards starting from the rightmost brackets* No. Java arrays are an **`Object` type**. You read it left to right, it evaluates left to right. – Elliott Frisch Jul 29 '17 at 01:24
  • @EJP The way you initialize 2D arrays using `new` in C++ like the accepted answer [here](https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new) is what gives me that intuition. – name Jul 29 '17 at 01:26
  • I look at it like declared dimensions. The last dimension is the only one that does *not* have to have a size; all others do since arrays are fixed size. – ChiefTwoPencils Jul 29 '17 at 01:28
  • @name If an user answered your question please also accept his answer ([Accepting Answers: How does it work?](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)). If not than please specify what remains unanswered, this is a really crucial part of StackOverflow, thank you very much. – Zabuzard Sep 24 '17 at 15:40

4 Answers4

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

new int [3][2];

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

new int [3][];

still makes sense. It still creates an array of 3 references, but the references are 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.

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

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.

Gene
  • 46,253
  • 4
  • 58
  • 96
1

You are probably thinking a bit too much in terms of 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.)

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.

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.)

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."

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • `int[][] a = { { 0 }, { 1, 2 }, { 3, 4, 5 }, { 6 } };` – Elliott Frisch Jul 29 '17 at 01:28
  • 1
    @ElliottFrisch is this supposed to be somehow telling me that I wrote something wrong? – Mike Nakis Jul 29 '17 at 01:28
  • 1
    Nope. Just a concrete example for OP of your aside about jagged arrays. Still not sure OP gets it. – Elliott Frisch Jul 29 '17 at 01:30
  • @ElliottFrisch I understand the concept of jagged arrays, just not why the 'inner' arrays are referenced from the first set of brackets in the array, not the second. It seems like it should be the other way around. None of this is new to me, I'm just having a crisis. – name Jul 29 '17 at 01:31
  • @name We don't have to use `[]` at all, consider `System.out.println(java.lang.reflect.Array.getInt(java.lang.reflect.Array.get(grid, 0), 0));` which is a really contrived example, but shows that Java really does consider an `int[]` a subtype of `Object` (with all that implies) - so an `int[][]` is also an array of arrays (as is an `int[][][]`). – Elliott Frisch Jul 29 '17 at 01:37
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.

Mohamed Benmahdjoub
  • 1,270
  • 4
  • 19
  • 38
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.

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.

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

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

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • _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._ And I have never questioned that until now, but it seems backwards. – name Jul 29 '17 at 01:33
  • You read from left to right. As in the math equation, first comes the outer and then the inner stuff, that is my intuition here. – Zabuzard Jul 29 '17 at 01:36