• Post Reply Bookmark Topic Watch Topic
  • New Topic

Multidimensional Arrays  RSS feed

 
Urs Waefler
Ranch Hand
Posts: 192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I do not understand the following code:
There are two times [] only. I would understand the code if there were three times [].

There is an other code I do not fully understand:
Of this code I understand: But I really do not understand this line:
I have an idea about multidimensional arrays, but I do not understand them fully. Please do not advise to go through a basic tutorial; I went several times through a basic tutorial but I do not understand multidimensional arrays.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Java does not have multi-dimensional arrays.  Every single array is one-dimension.

HOWEVER...

Arrays can hold all kinds of things...including (and here's the catch) arrays.

So this:



Really means "i want an array that holds references to arrays of ints".  Then, due to some compiler magic, you are allowed to create the arrays this will refer to, and assign all the references, all in one fell swoop.  So, you create three arrays - the first with "1,4", the second with "3", and the third with "9,8,7".

so differentsize is an array, with three elements, each of which is a reference to one of those three arrays we just created.



 
Urs Waefler
Ranch Hand
Posts: 192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider these two codes: and How do you explain the difference?
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
one compiles and one doesnt.

The first says "i want an array that points to things that are arrays (that hold ints)".  Through Java magic, when you say "{{1,4}, {3}, {9,8,7}};", you're creating three arrays, with 2, 1, and 3 elements respectively.  differentsize[0] will point to the array that holds 1 and 4.  differentsize[1]  points to an array that holds "3".  differentsize[2]  points to the array that holds "9,8,7".

The second says "i want an array that points to an array <that holds arrays>".  But you don't give it that. you try to initialize it to point to arrays that hold ints. So, the compiler complains.
 
Urs Waefler
Ranch Hand
Posts: 192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I begin to understand. Still I do not fully understand the following code: ia.length seems to be the first "hierarchy", it is a kind of the top "level". After you follow the path. But I do not fully understand the concept - please help.
 
Knute Snortum
Sheriff
Posts: 4288
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The variable ia is an array.  ia.length is the number of elements in that array.  Let's call that height.  ai's elements contain arrays.  ia.[0].length is the number of elements in the first array. Let's call that width.  ia.[0]'s elements contain arrays.  ia[0][0].length is the number of elements in the first array's first array.  Let's call that depth.

So if we think of ia[][][] as the dimensions of a cube, you could that ia.length is the height of cube, ia.[0].length is the width of the cube at height 0, and ia.[0][0].length is the depth at height 0, width 0.

The cube analogy is not perfect, because each array in an element may have a different length.  So ia[0].length may not be equal to ia.[1].length and so on.  This is why so many of us at CodeRanch say, "Java doesn't have multidimensional arrays."
 
fred rosenberger
lowercase baba
Bartender
Posts: 12565
49
Chrome Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a chicken farm.  My chickens lay eggs.  I need to get those eggs from my farm to a store, because...well...i like money.

Now, it doesn't make sense to send each egg individually. I need something to hold a collection of eggs.  Something like an egg carton.  Now, some people like to buy 6 eggs at a time, some 12, some buy 18.  So I need egg cartons of different sizes, but they can all hold eggs.  An egg carton is like a 1-d array that holds eggs.

Now...it's a pain to ship every single egg carton.  It's be nice if I could have some larger container that holds egg cartons...like a crate.  It can hold multiple cartons of different sizes.  So I may have a crate that hold 12 cartons, and the first carton hold 12 eggs, the second carton holds 6, the third carton holds 36....So now i have an array - my crate - that holds arrays - my cartons - that hold eggs.

to explicity call out the differences, a 2-d array would be a box with eggs laid out in a rectangle. You could go to the third row, and the 4th column, and pick up an egg.

Java has 1-d arrays.  My crate only holds one thing - egg cartons.  If i open up the crate, and look at the 3rd thing in it, it will be an egg carton. I can then open up THAT, and look inside that carton and find an egg.

You can continue the analogy up to a palatte that holds multiple crates, and then a truck that holds multiple palates, then a fleet of trucks that has trucks...then the analogy kind of breaks down...


Back to your original post...

int[][] differentsize = {{1,4}, {3}, {9,8,7}};

Says "i want an array that holds things.  Those things happen to be (arrays that hold ints)."  Java lets you get away without declaring the size of your initial array if you then tell it exactly what goes in it.  Inside your first set of curlie braces are three arrays, so your differentsize array is created to hold three things.
 
Urs Waefler
Ranch Hand
Posts: 192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In fact I do not need an analogy or an image. To be frank I understood the term dimension when I was 17 years old already. There are three dimensions, our consciousness can perceive these three dimension. After I thought about a fourth dimension - it is time. The fourth dimension is time, the fith dimension is the time in square, the sixth dimension is the time cubed. Some years later I studied physics at the Swiss Federal Institute of Technology Zurich, what I regognized when I was 17 years old is the basic of Albert Einstein's theory of relativity.

The term dimension in Java is abstract. I do not have any problems with this term. What I do not fully understand is the numbering.
Let me try to make it more clear: Initially there is: But it is not like that: My problem has more to do with the syntax, the notation.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To understand the notation, you need to be able to visualize the organization of the array that has been declared.

When you declare int[][] ia, that means you have something that looks like this:
ia[0]ia[1]...
int[] {...}int[] {...}...

So, the array ia can be initialized as { element0, element1, element2, ... }

Where element0, element1, element2, etc. are all int[]

Declaring and initializing like this:

gives you this:
ia[0]ia[1]ia[2]
int[] {1, 4}int[] {3}int[] {9, 8, 7}

So, when you reference ia[0][1], you are accessing the first int[] with the 0 index, which is {1, 4}, then accessing the second element of that array with the 1 index, which is the number 4.

The array you declared is called a jagged array because the nested arrays do not all have the same length. So, if you try to access ia[2][2], you'll be fine and that evaluates to 7. However, if you try to access ia[0][2], you'll get an IndexOutOfBoundsException because the array ia[0] only has 2 elements and the largest index you can use with it is 1 (for the second element).

Clear as mud yet?
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Furthermore, you can treat each element of a nested array as you would any array. That is, if you have

Then you can do this:
 
Liutauras Vilda
Sheriff
Posts: 4928
334
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@OP
Reading all that, isn't clear exactly which parts confusing you most, so, will try to cover bit by bit some of them. Other guys already covered a lot, but might other phrases will give you different angle.

The best way I think to understand multi dimensional arrays as you call them, is to use right terminology for a start, which is Array of Arrays, that gives pretty clear picture and intuitiveness in my opinion.
So how we can understand that?

1. Array of Arrays, to me means, there is an array, singular, not plural, which holds arrays:
int[][] A = new int[2][3];
So what you have here is, an array at first:
{...}

2. Now look to the other side, it defines how many elements it can hold:
int[][] A = new int[2][3];
So how you can look at it:
{something, something}

3. Let's move on, lunch will come that way soon, you see another pair of [], that says that those two elements are arrays:
int[][] A = new int[2][3];
So now you know that something is an array, so you have:
{{...}, {...}}

4. Next, you look again, how many elements it has, look to the right:
int[][] A = new int[2][3];
{{something, something, something}, {something, something, something}}

5. What you have in place of something? Well, no more pairs of [], you have defined data type int, so ints are there:
int[][] A = new int[2][3];
{{1, 2, 3}, {1, 2, 3}}

----------------------------------------

Now how you access them, simple enough.

So, once you specify:
A[0]
It gives you outer/top level so to speak array element, it returns something what you had at step 2, which is something, but from step 3 you know that something is an array of int's. So if you want to assign this value to something, you need to declare as an array:
int[] B = A[0];
And what you get is
{{1, 2, 3}, {1, 2, 3}}

Now, if you specify:
A[0][1]
Gets intuitive, isn't it? You know what you got from A[0] was an array, so the number from second pair of [] gives you A[0][1]
{{1, 2, 3}, {1, 2, 3}}

Imagine there were:
int[][][] C = new int[2][3][3];
That would be as simple as:
{ { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} }, { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} } }

And again, if you'd write C[0], you'd get outer array first element, out of two existing.
int[][][] C = new int[2][3][3];
{ { something, something, something }, { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} } }

I used something to have less {}, but you know already, that those something are arrays too.

Got a bit long with all that.

I hope clear?

One more time, lets choose random indices C[1][2][0], so what we get?
C[1][2][0]
{{ something, something, something }, { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} } }

Next:
C[1][2][0]
{{ something, something, something }, { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} } }

Next:
C[1][2][0]
{{ something, something, something }, { {1, 2, 3}, {1, 2, 3}, {1, 2, 4} } }

We are done

 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:
5. What you have in place of something? Well, no more pairs of [], you have defined data type int, so ints are there:
int[][] A = new int[2][3];
{{1, 2, 3}, {1, 2, 3}}

Just so there's no confusion, when you declare the array like this:

what you have in memory is this:

That's because int arrays will have their elements initialized to 0. Arrays of reference types will have their elements initialized to null, which is why you'd get a NullPointerException if you make a mistake and try to call a method on an array element that hasn't been assigned a valid reference. Boolean array elements are initialized to false.

It's also legal to only partially allocate/size a nested array:

The above initialization results in:

If you're wondering why that's not {0, 0, 0}, it's because the "outer" array is an array of int[] and int[] is a reference type and as I wrote above, elements of arrays of reference types are initialized to null.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also note that when partially allocating nested arrays, you have to keep empty "dimensions" to the right. You'll get a "Cannot specify an array dimension after an empty dimension" compile-time error if you try something like this:

If you think about it, that makes sense because Java wouldn't know how many int[3] elements to put in the outer array of int[].

Now, you might wonder why new int[2][3] results in {{0, 0, 0}, {0, 0, 0}} instead of {{0, 0}, {0, 0}, {0, 0}}.  The latter is the result of new int[3][2]. But why?

I can guess a number of reasons for doing this:

1. (Historical) This mimics what C and C++ do and Java syntax was purposely made to closely resemble C/C++ syntax to facilitate learning/retooling.
2. (Technical) It's easier for parsing/lexing (maybe?)
3. (Cognitive) Seems more natural to think of outer->inner reading from left->right

Mind you, these are just my guesses. You'd have to ask the Java designers why they designed Java this way for the actual reasons.

 
Liutauras Vilda
Sheriff
Posts: 4928
334
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nice addition by Junilu.

Junilu is quite pedantic from what I have observed. Which is a feature I like a lot t. I am too. Hence that merits correction clarification:

Junilu Lacar wrote:However, if you try to access ia[0][2], you'll get an IndexOutOfBoundsException because the array ia[0] only has 2 elements

More precisely, that would give ArrayIndexOutOfBoundsException, which in general IS-A IndexOutOfBoundsException, as the former extends latter.
 
William Ng
Greenhorn
Posts: 16
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Urs Waefler wrote:
The term dimension in Java is abstract. I do not have any problems with this term. What I do not fully understand is the numbering.
Let me try to make it more clear: Initially there is: But it is not like that: My problem has more to do with the syntax, the notation.


You are making this more complicated than it is. The variable ia is already an array. So it's type is an array type. It does not make since ot have to say ai[].length. Because in java and most langagues, the [] is the method of accessing elements in the array. What would you be accessing with a[0].length? You would be acessing the first element which is an array,as specified in the declaration.
That is why to get the length of the array, it is

From there, each [], will refer to the next dimension.
Referring to your analogy, ia would be the first dimension That is itself is a dimension. That is why it is proper to refer to it as above.  In two dimensions, there is another dimention. And if, the first dimension is ia. the second one would be its elements. In three dimensions the elments of the second dimension are also arrays. Get it?
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can see how people might get confused with the notation though. This might not be the case for OP but here's a different way of looking at the series of [][]...[] when you declare an array of arrays of arrays of ... :

IMPORTANT NOTE: What follows IS NOT how Java is actually designed. The description below just gives an alternative interpretation that some people might mistakenly have.

This actually also kind of makes sense to me but the Java designers might have thought it would be counterintuitive to more people than not.

You could group the pairs of [] in a "multidimensional array" declaration this way:

Since int[] a is an array of int and follows the general pattern elementType[] variableName

One might reason that the declaration 

should be interpreted as

given that int[] would be the elementType of the array, a. So the second pair of [] is what says that a is an array and the first pair of [] is associated with the int and declares the elementType of int[].

In other words, given a declaration of the form elementType[] a which declares an array a with elements of elementType, then the declaration

int[][] a;

declares an array, a, with elements of type int[].

Now, since the second pair of [] is what says that a is an array and the first pair of [] is associated with the type int, which makes up the int[] which is the type of elements in array a, then shouldn't the second pair of [] correspond to the (outer) dimensions of a instead of the first pair of []? Conversely, shouldn't the first pair of [] correspond to the inner array dimension?

By this reasoning, one might expect that a declaration of int[][] a = new int[2][3] would give you this instead: {{0, 0}, {0, 0}, {0, 0}}

The way Java was designed, as I said up top, it doesn't.

I hope that makes sense.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:Junilu is quite pedantic from what I have observed. Which is a feature I like a lot t. I am too.

That's not usually given as a compliment but in this case, that's how I'll take it.

And now I have "features", too! So, I'm like a pedantic robot then? 
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
William Ng wrote:
You are making this more complicated than it is. The variable ia is already an array. So it's type is an array type. It does not make since ot have to say ai[].length. Because in java and most langagues, the [] is the method of accessing elements in the array. What would you be accessing with a[0].length? You would be acessing the first element which is an array,as specified in the declaration.

@William, OP is simply trying to get the concepts straight in his mind. It's natural for beginners to have a topsy-turvy mental model and until they can reconcile that mental model with reality, then it will always appear to those who "get it" that beginners are making it more complicated that it is. In many respects, these concepts are like a Columbus Egg: if you get it, it's simple and straightforward; if you don't, it's difficult and complicated.

There are many valid reasons to want to use the expression ia[0].length. That expression actually gives you the number of elements of the first array in an array of arrays.
 
Urs Waefler
Ranch Hand
Posts: 192
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot for these explanations. Sligthly I develop an understanding. I think, there is a difference between the left side and the right side; the meaning of [] seems not to be exactly the same.
This code fails to compile because the dimension is missing.
However this code compiles, the array has the dimension 5. After you can write: 0 has nothing to do with the dimension, it is the location. What is the meaning of the number of []? The dimension is 5 in this case. It is really strange that I can not compile The code looks like that: It fails to compile.

Let my try a so called multidimensional array. This is a 2 dimensional array which holds one array with 4 dimensions and one array with 5 dimensions.
 
Liutauras Vilda
Sheriff
Posts: 4928
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought we explained quite well. Stop using word "dimension", that is some kind of clever word which confuses you. All what you said abou what compiles and what not seem to be wrong, because of other mistakes. Line 4 for instance. You cant do that - has nothing to do with arrays or something else.

 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are using the wrong terminology.  A "dimension" is the number of levels of nesting of arrays.  The answer to your question, "What is the meaning of the number of []?" is: It tells you how many levels of nested arrays you have (i.e., how many "dimensions").

So, an array declared with three pairs of [] like int[][][] space can be used to represent a three-dimensional coordinate system with x, y, and z axes.  On the other hand, an array declared with only two pairs of [] like int[][] plane can be used to represent a two-dimensional coordinate system with x and y axes.

What you are referring to as "dimension" in an array declared as int[] a = new int[5];, and you say "the array has 5 dimensions" is incorrect terminology.  That array has ONE dimension.  It has FIVE elements; in other words, the length of the array is 5.  As in the real world, "length" is a dimension, just as "width" and "height" are dimensions. The measure of something along a dimension is what's called the length or more formally, it's magnitude and is expressed in the number of units. With an array, the units are called "elements".

Dimensions != Elements

 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Urs Waefler wrote: It fails to compile.

As Liutauras said, that has nothing to do with your original question. That is a syntax error. You can't have an assignment statement like that outside a method or initialization block. The reason line 3 compiles is that it's a declaration that just happens to include an optional initialization. That, on the other hand, is legal.  you should know the difference.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!