Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

back to basics with multi dimensional arrays  RSS feed

 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Ok guys so this is really going back to basics here but I came across some code on skillshare that kind of had me thinking and wondering about multi dimensional arrays




so firstly it's a 2d array,how come there is four sets or four arrays would this be similar to declaring the array as



?

secondly in the nested for loop how come it's possible to use data[i].length?  since it's a 2d array should it be data[i][i] or data[i][j]?


thanks
 
Fred Kleinschmidt
Bartender
Posts: 560
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The first problem is that in the code snippet shown, there is no variable named 'data'. It should probably be using 'array'.

The variable 'array' was declared as an array of 4 arrays; Each of those arrays is declared to have length 3.

array[0] is an array of three ints. If x is an array, its length is x.length. So the length of the array array[0] is array[0].length.

Note that it is not necessary for the array to be square; it is possible for each array[i] to have a different length

 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:. . . firstly it's a 2d array . . .
No, it isn't, because Java® doesn't support 2D arrays. This is what the memory looks like if you have a 2D array:-But what you actually have is this:-In the case of a 2D array, which I had to deal with in older C implementations, all the elements are consecutive and it was possible to write such horrors as myArray[0][3]. In Java®, the array contains other arrays and their contents are in different memory locations. That is an array of arrays, and it is the only kind of array nesting you can have in Java®. Anybody telling you that is a 2D array is mistaken.

That means all the elements are arrays in their own right so myArray[i] either gives you a sensible answer for trying to find its length field, or throws an Exception because you have gone out of the bounds of the indices.
would this be similar to declaring the array as


? . . . thanks
Yes and no. If you declare new int[4][3], you get a structure like this:-. . . because arrays are filled with 0s or something else non‑specific until you fill them with something else. Note it has the twelve memory locations in the same arrangement as before, which is the similar bit. This is why I like the array initialisers as in
int[][] array = {{1,2,3}.{4,5,6}.{7,8,9},{10,11,12}};
That fills the array from the word go. It isn't too bad with int[]s because 0 is a valid value for an int, but it can be dangerous if you write this sort of thing:-
String[][] wordSquare = new String[4][3];
That will give you a structure as above with the twelve numbers as before, but each 0 now represents a null. Twelve of them for the price of one, and as you know, a null can be dangerous.

The few times I have tried 2D arrays on the more recent C implementations, they appeared to have been implemented as arrays of arrays like in Java®, rather than 2D arrays.

I hope you are indenting your code better in real life than in your post on this thread. Don't write so many blank lines; they don't help legibility.
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fred Kleinschmidt wrote:. . . it is not necessary for the array to be square; it is possible for each array to have a different length
That is one of the advantages arrays of arrays have over 2D arrays. Also you can reassign them so as to change the sizes of the individual arrays, so the whole thing changes shape.
 
Liutauras Vilda
Marshal
Posts: 4640
316
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know some people thinking - we say way too often that Java does not have 2D arrays. Since I never programmed in a language/-s which truly support 2D arrays, I don't know the real strong argument about that or difference. People with more experience could tell you more.

But I know that Java has array of arrays. And if you think for a moment about the words array of arrays, that helps to understand that stuff or eliminate confusion many beginners have in nowadays. I was struggling about 2D arrays too when I have been told about them as about 2D arrays. They have mentioned 3D and 4D, but that was too much at that time.

Alright, we know by now, it is an array (singular) of arrays.

1. {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}
So, what you see in between those bolded curly braces, is an array of 4 elements. Clear, right? This is how you initialize them in Java.

2. {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}
Other bolded curly braces define 4 elements which appear to be arrays too. And each of them have 3 elements in it (of primitive type - int).

3. Now, everybody knows how to access array elements. It is as simple as:
A[0] - first element
A[1] - second element
A[2] - third element
A[3] - fourth element

Everybody also knows how to check length of the array. It is A.length.

So, if we check A.length, we get 4, this is what array from point 1 contains. Since we know, that its elements are also arrays, and we also know how to access array elements, then writing A[0].length also makes sense, right? It gives first element which is an array, and array's length we check with length.
----------------------

Now, how you access particular int element?

A[2][0] - third element in an array (from point 2) = {7, 8, 9}
{{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}

A[2][1] - third element's (which is array) second element = 8
{{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}}

That is pretty much it. As been mentioned, not all elements, which are arrays too, lengths need to be the same. That is why is important in the loop to have:
i < A[i].length so you wouldn't go out of index range in case one of those elements (arrays) length is different from any other.
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:I know some people thinking - we say way too often that Java does not have 2D arrays. Since I never programmed in a language/-s which truly support 2D arrays, I don't know the real strong argument about that or difference. People with more experience could tell you more.

2D arrays are contiguous blocks of memory, much like a regular array, except cell access requires a pair from the cartesian product of the input domains. Example:

Here's how you can model a 2D array in Java:
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It used to be possible for me to write this sort of thing in C:-Line 3: Remember that an array is equivalent to a pointer in C. Prints address.
Line 4: Contents of the first pointer
Line 5: array[0][0] is identical to *array in line 4.
Line 6: Move 3 memory locations on from array and you are into the second subarray
Line 7: This abomination allows you to violate the bounds of the array. Remember that C/C++ does little or nothing in the way of array bounds checking.
Newer C implementations seem to implement that as an array of arrays.Line 2: Address of beginning of array:  printf("%p\n", matrix); gives the same output.
Line 3: Address of first subarray, in decimal.
Line 5: Contents of pointer offset by 3: Address of fourth subarray. We have passed 9 ints each of 4 bytes, so the memory address increases by 36 (=0x24). This would appear to be a sort of hybrid array with the four subarrays indexed as if arrays of arrays but in consecutive and contiguous memory.
Line 6: Contents of memory location of fourth subarray: equivalent to matrix[3][0].
Line 7: Still able to violate array bounds.

Athough in the newer GCC, such arrays are implemented as arrays of arrays, the necessity to quote sizes for all dimensions except the first limits to type of array to rectangular arrays. Any attempt to write a jagged array annoys the compiler:-Line 8: This is the output from printf("%d\n", matrix[3][5]); Note it didn't print 14. The compiler only issued a warning about the jagged array but an incorrect output was found at runtime
So Java® has the advantage over C that its implementation of arrays of arrays allows for jagged arrays, and also allows the size of subarrays to be changed:-Line 4 replaces {3, 4, 5} by an empty array (= zero‑length;). I couldn't get that sort of thing to compile with GCC.
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To have a jagged array of arrays in C, you could do something like this:

It's worth noting that this isn't *really* an array of arrays, but rather an array of pointers.
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:. . . that this isn't *really* an array of arrays, but rather an array of pointers.
Aaaaaaaaaaaaaaaaaaaaaaaaaah! Nice!

Your code is slightly different from mine in that you have a little * in line 1, so you are explicitly declaring that as an array of pointers. Are you now stuck with arrayOfArrays[3] having six elements for ever? Probably not, because you can replace the contents of the pointer in arrayOfArrays[3].
 
Liutauras Vilda
Marshal
Posts: 4640
316
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I will censor you both in a minute

I think OP and everybody else who reading this thread will remember now, that Java does not have 2D arrays as that would be too complicated. It is hard enough for many to grasp concept of array of arrays.
 
Liutauras Vilda
Marshal
Posts: 4640
316
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
2 cows were spread on 2 2D arrays posts. That's a one of rare cases where 2D term was used legally.
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:It used to be possible for me to write this sort of thing in C:-Line 3: Remember that an array is equivalent to a pointer in C. Prints address.



thanks guys for all the replies,I'm going to learn a lot from this thread =)


Yes I remember reading in a c++ book that in c and c++ multi dimensional arrays are contiguous in memory,so in Java this is not the case?
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sorry I should have put this in one post,

also in c++ it's possible to leave out the first index [] bracket of the array when using a multi dimensional array so when passing an array you could put array[][6] as far as I know,is this also possible in Java I'm guessing not if multi dimensional arrays aren't contiguous blocks in memory

thanks
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Fred Kleinschmidt wrote:. . . it is not necessary for the array to be square; it is possible for each array to have a different length
That is one of the advantages arrays of arrays have over 2D arrays. Also you can reassign them so as to change the sizes of the individual arrays, so the whole thing changes shape.


I'm going to be a mathematical pædant here just to nail down some points.

In strict mathematical terms, a 1-dimensional array is a vector. A 2-dimensional array is a matrix. The Fortran and COBOL programming languages supported arrays of up to 3 dimensions, and C/C++ even more (some early implementations gave up at 8, I think).

In Java, only vectors are supported, and notably that includes sparse vectors (elements with nothing in them). To get a "multi-dimensional array", you have to have a vector whose elements are vectors. And also note, please that java.util.Vector isn't the same thing as a mathematical vector. Vector is really a resizeable list (a là java.util.List) with synchronization. A java "array" (vector) is not resizeable. In fact, it's immutable, although its element references are not.

This can be a little annoying if your primary focus is in regular multi-dimensional collections, but it does have the advantage of allowing many other options, such sparse arrays. Or vectors of Maps or even vectors of heterogeneous objects,
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:Yes I remember reading in a c++ book that in c and c++ multi dimensional arrays are contiguous in memory,so in Java this is not the case?

Arrays by definition are always implemented as contiguous blocks of memory, regardless of their dimension. Java doesn't have multidimensional arrays, only linear ones.
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The same syntax may stand for a different concept in different languages:

In C, int array[][] is a two-dimensional array of ints.

In Java, int array[][] is an array of arrays of ints.
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:. . . thanks guys for all the replies
That's a pleasure
I'm going to learn a lot from this thread =)
So will everybody else involved in this thread, or reading it. That is one of the reasons we post at all.
Yes I remember reading in a c++ book that in c and c++ multi dimensional arrays are contiguous in memory,so in Java this is not the case?
I think Stephan has already answered that. There ain't no such thing as a multidimensional array in Java® at all. Look at the 3rd post in this discussion, my first one. You can see in the second code block that I have the numbers on different rows. The first row shows the references to the individual arrays all on one line, then you have four lines with the included arrays. I wrote that to represent the fact that although each array has its elements in consecutive and contiguous memory locations, they are on different rows and may be separated in memory.

NB: When I said consecutive, I didn't mean that the byte numbers are consecutive the way 1 2 3 are consecutive. I meant that the w‍ord numbers are consecutive, and words occupy 4 bytes or 8 depending on the type of machine and OS. Not 1 2 3 so much as 0 4 8 when you convert the words back to bytes.
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the cow, whoever it was
 
Liutauras Vilda
Marshal
Posts: 4640
316
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:In Java is an array of arrays

And I think it is important to emphasize, that it is a singular array, rather than arrays of arrays. Because there is always one array A.length, which possibly holds more arrays, which possibly hold more arrays.
 
Tim Holloway
Bartender
Posts: 18709
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:
Stephan van Hulst wrote:In Java is an array of arrays

And I think it is important to emphasize, that it is a singular array, rather than arrays of arrays. Because there is always one array A.length, which possibly holds more arrays, which possibly hold more arrays.


Which is why I emphasized that Java uses the term "array" when technically it's always a vector.
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
so how do we go about making an array of arrays that holds more arrays

this block of code didn't do it



 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sorry guys I should have just used one bracket while creating the arrays

should have been

 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
scratch that,that code actually won't work

 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't do that. array2 is an int[][], so array2[i] is an int[], so array2[i][j] is an int. You can't assign a new int[4] to a variable of type int.
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can do this though:
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Stephan

alluding to your example how come you would leave the second square bracket empty and could we still do this let's say if we had [4][4] instead of [4][]?

thanks
 
Stephan van Hulst
Saloon Keeper
Posts: 7808
142
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
int[][] is an array of arrays. Since it's a reference type, the default value is null. You can initialize it with an explicit size by providing the size between the first pair brackets. new int[4][] will give you the following array of arrays:

Java allows you to also initialize each of the cells of the array with a new array of some size. You do that by specifying the size of each array between the second pair of brackets. new int[4][4] will give you the following array of arrays:

Let's take a hypothetical situation. You need an array of arrays that's the form of a staircase:

You can create it like this:

Now, if we had initialized the array with new int[4][4], each cell of the array would have been initialized with a new array instance of size 4, only for them to be replaced by another new array instance in our loop. To avoid the useless creation of 4 new array instances, we leave the second pair of brackets empty.
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
that makes sense =)
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How would you write that staircase array with Streams rather than a loop?

AC: Note it is possible to fill an array with an (overloaded) method of the Arrays class.
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am sure there will be better ways to create that staircase array than this:-
 
Piet Souris
Rancher
Posts: 1980
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why limit to a staircase? Use your imagination:

Anyone any idea about antialiasing for such arrays?
 
Campbell Ritchie
Marshal
Posts: 55715
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does antialising mean that array[2.5] has a length of 2.5?
 
Adam Chalkley
Ranch Hand
Posts: 512
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
who ever gave the cow

thanks for the cow =)

much appreciated
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!