Selectively allocate dimensions for multi-dimensional array at construction - java

Java supports multi-dimensional arrays, which are represented as "arrays of arrays". For instance, I can create an array of String arrays using the following code:
int rows = ...
int cols = ...
String[][] array2d = new String[rows][cols];
What I'd like to do is have the second dimension be "nulled out". In other words, a for-loop like for(String[] array : array2d) System.err.println(array); would print out:
null
...
null
The reason I'd like to do this is because I have already allocated a bunch of String[] instances that I want to just drop into array2d. I have a couple of solutions but both seem sub-optimal for the following reasons:
Solution 1
I could just do something like String[][] array2d = new String[rows][0], use a for-loop to null out the first dimension, and populate the rows later, but this seems ugly to me because Java will create a new empty String[] for every row, and I really don't need it to.
Solution 2
I could also do something like String[][] array2d = new String[][]{null, null, ... null}, but this is even worse because I have to hard code the length of the first dimension of array2d via the bracketed section of code, which is disgusting.
I recognize that this isn't a huge problem, especially when the dimensionality is small, and any programmer worth his salt would choose some other construct over creating arrays of many dimensions. I'm mostly just curious if there is a way to partially allocate dimensions of a multi-dimensional array at construction.

Easiest solution possible:
int rows = ...
String[][] array2d = new String[rows][];
If you don't initialize the second dimension, you array will have null entries in dimension 1.

Related

Why second dimension is not mandatory in 2d array in java?

int a[][]=new int[2][]; // It works without any error
Why is the second dimension missing in this snippet?
A 2D array is, technically, an array of arrays. The code that you have specified tells you how many arrays you want to have.
You can further initialize this as follows:
int a[][] = new int[2][];
a[0] = new int[3];
a[1] = new int[5];
Something like new int[2][2] is nothing more than a condensed version of the code above.
It's not mandatory because the second dimension is not required to calculate how much memory is required to hold the array.
Compare the following:
int[] a = new int[2];
In this case the JVM needs to be instructed to allocate space for one array that holds two integers.
On the other hand:
int[][] = new int[2][];
In this case the JVM needs to be instructed to allocate space for two references to integer array objects. It doesn't matter what size these integer array objects end up being, as it doesn't change the size of the reference.
In fact, these two arrays can have different sizes or even not be created at all.
Second dimension in array is optional in Java. You can create a two dimensional array without specifying both dimension e.g. int[4][] is valid array declaration.
The reason behind that is Java doesn't support multi-dimensional array in true sense. In a true two dimensional array all the elements of array occupy a contiguous block of memory , but that's not true in Java.
Instead a multi-dimensional array is an array of array. For example two dimensional array in Java is simply an array of one dimensional array like String[][] is an array of array of String[] or "array of array of strings". This diagram shows how exactly two dimensional arrays are stored in Java :

User defined Array dimensional and size

I have unsolvable task, I have task, where i have insert random number to array. The user can choose if array is 1D, 2D, 3D,size of array is optional . I tried everything but withot success. I can not use ArrayList.
Thank you for help.
double[] array= new double[size];
for ( int i;i<dimensional;i++)
{
double[] array= new double[size];
}
Edit:
I mind if is effective way to create array with 1D and then add to this array one or more dimension.
Multi-dimensional arrays in java are essentially just arrays of arrays. The user provides the number of dimensions and sizes at runtime so you need to dynamically build this array at this point. It's a strange problem, and not one that you would try to solve with arrays in production code, but nevertheless it should be possible. Try the accepted answer for this question, it seems like a pretty good attempt.
So, an "unsolvable" task ... well, as long as you work with primitive types and the dimension can be theoretically any number (only limited by memory available), you may be right.
You can however use some kind of object (Java is an object-oriented language) and solve the task rather easily. Basically, you might want a tree structure with nodes. You can even write a constructor that sets fixed sizes for every level and give no direct accessors to the array as a whole. Start with:
class Node {
double payload;
Node[] children;
}
I don't really understand what do you want to do with that, but it pretty much fits the idea of N-dimensional array.
Another solution: Make the array one-dimensional, but using the sizes of the individual dimensions, you can calculate the correct index. Of course, it will require you to handle the logic.
E.g. in a 2D array of 3x3 size, you can use a 1D array of 9 size and use first three indexes for first row, next three for second row, last three for third row. You can then use a cycle like this:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//arr[i * 3 + j] = ...
}
}

In terms of localizing data for caches, are java multi-dimensional arrays Col-Major or Row-Major?

I found this topic on a similar Stack Overflow thread.
In c++, when you make an array int[i][j] you get row major order, so iterating by row will give you caches which contain more useful data.
In java, there is no 2d array, but it still creates something similar enough in terms of caches. My question is, does it create the arrays of actual data in the size of row, or does it create the array of pointers in size of row?
Or, as the top answer on the similar Stack Over thread said, does it do something entirely different where int[5][8] would be an array of 5 pointers to arrays of any size that all add up to (5*8)?
It said java makes jagged arrays, and I can't think of any good reason for this to be true.
In java, there is no 2d array, but it still creates something similar enough in terms of caches
I don't know about the C++ behaviour, but it sounds like you're expecting something in the Java behaviour which may very well not be the case. If you write:
int[][] x = new int[5][8];
then that's equivalent to:
int[][] x = new int[5][];
x[0] = new int[8];
x[1] = new int[8];
x[2] = new int[8];
x[3] = new int[8];
x[4] = new int[8];
There are 6 separate arrays here. At any point, you could write:
x[2] = new int[10000];
It's just an array of arrays - jagged by definition. There's nothing to say it'll stay rectangular forever, or even that all the elements of the "top-level" array will be non-null.
I'd expect the values to start off close to each other in memory, but there's no guarantee that they'd stay that way.
If you really want to make sure you have a contiguous block of memory, you should use int[] x = new int[40]; instead.

Test length of multiple dimensions of an array in Java

I'm a Java noob. I don't know very much about the language (at least, not enough to do complex things) right now, but I'm getting there!
I know you can test the length of a single-dimensioned array by doing arr.length, but is it possible to test other dimensions (in a multidimensional array)?
Yes, it is. Obviously, to test the first dimension you would just do arr.length. Subsequent dimensions are tested by using length with the [0] element of that particular dimension. For example, consider this array:
int[][][][] arr = new int[10][11][12][13];
To test the...
first dimension: arr.length;
second dimension: arr[0].length;
third dimension: arr.[0][0].length;
fourth dimension: arr.[0][0][0].length;
A multidimensional array is just an array of arrays, and each array in the array can have different lengths. I.e.:
int arr[][] = new int[2][];
arr[0] = new int[5];
arr[1] = new int[10];
System.out.println(arr.length);
System.out.println(arr[0].length);
System.out.println(arr[1].length);
Now you have a two-dimensional array. The first dimension (outer) can be referred to as arr and is of size 2. The inner arrays can be referred to as arr[0] and arr[1] and have lengths 5 and 10, respectively. Since each of these refers to a normal Java array, you can use all the normal ways of accessing an arry on them. Further, since we create multidimensional arrays by putting arrays in arrays, you can have as many dimensions as you want, and you access each further level down by indexing into the one above: arr[2][1][5][11][3][0][123][5][42][9][7]....length
Given, say, a 2D array, you can access the length of the ith inner array with arr[i].length.
If you haven't already seen it, check out Arrays (The Java™ Tutorials).
You can test the other dimensions of the other dimensions by directly referrencing the dimension you are wanting to test.
For example, if you have a 2 dimensional array with 3 items in the primary dimension then you can identify the length of each of them by using arr[0].length, arr[1].length, and arr[2].length.
the code below just sets up an array, and then verifies that the lengths are what we expect them to be.
public void testLength(){
//setup the array you are wanting to test
int[][] foo = new int[2][5];
// this just makes sure that we do get 2 dimensions within the primary
Assert.assertEquals(2,foo.length);
Assert.assertEquals(5,foo[0].length);
// change the array stored within foo[0]
foo[0]= new int[8];
Assert.assertEquals(8,foo[0].length);
}

Java native array lengths

I have a 2D array of doubles in Java which is basically a table of values and I want to find out how many rows it has...
It is declared elsewhere (and allocated) like this:
double[][] table;
then passed to a function...
private void doSomething(double[][] table)
{
}
In my function I want to know the length of each dimension without having to pass them around as arguments. I can do this for the number of columns but don't know how to do it for the rows...
int cols = table[0].length;
int rows = ?;
How do I do that?
Can I just say...
int rows = table.length;
Why would that not give rows x cols?
In Java a 2D array is nothing more than an array of arrays.
This means that you can easily get the number of rows like this:
int rows = array.length;
This also means that each row in such an array can have a different amount of elements (i.e. each row can have a varying number of columns).
int columnsInFirstRow = array[0].length;
This will only give you the number of columns in the first row, but the second row could have more or less columns than that.
You could specify that your method only takes rectangular arrays and assume that each row has the same number of columns than the first one. But in that case I'd wrap the 2D-array in some Matrix class (that you might have to write).
This kind of array is called a Jagged Array.
Look at this example. They use .length there to get the row count, [].length to get the column count.
It's because the array consists of "row" pointers and these could lead anywhere, so you have to use .length for each column to get the sizes of these arrays, too.
I don't quite understand your question. You have to realize that in Java, multidimensional arrays are in fact arrays of arrays.
table.length will in fact give you the number of one-dimensional arrays contained in your two-dimensional array (assuming there are no null entries).
table[0].length will give you the size of the first one-dimensional entry. This could be different from the size of the others, and it could throw a NullPointerException (though neither is possible when it's allocated as new double[rows][cols]).
Well, first of all, why don't you just test if
int rows = table.length;
gives the desired result?
It does indeed give you the number of elements in the first dimension. Multidimensional arrays are in fact nothing special, as they are just arrays of arrays of arrays of ... In your case - a 2D array - it is organized like this (in pseudo-code):
double[][] foo = { double[] = {...}, double[] = {...}, ... }
So when accessing foo, it refers to the "outer" array, which has of course the length property, which contains the number of arrays it contains on the second level.
You can read the double[][] as "An array ([]) of double-arrrays (double[])".
No it won't. You can just use table.length
Alternatively, you could wrap your 2d array into a Matrix or Grid class of some sort. Internally, you could represent it as a 1d array and compute offsets for the row/col coordinates.

Categories

Resources