I want to build a 2D array from N (one-dimensional) arrays. The only problem is, as far as I can tell, the only way to declare a multi-dimensional array in Java requires you to specify all inner dimension sizes, and those sub-arrays get created. In this case, this seems wasteful, since they will be overwritten
In C++, I could do this:
Object** arr = new Object*[n];
for(int i=0;i<n; ++i)
{
arr[i] = getObjArr();
}
In Java, you have to say this:
Object[][] arr = new Object[n][0]; //inner dimension is required
Each of those n zero-length arrays will be created, only to get overwritten as the array is populated. Is there a way to declare a multi-dimensional array (similar to the pointer to pointer(s) syntax of C) without allocating the inner arrays?
Sure. I don't know why you think you have to do that!
double[][] foo = new double[2][];
is perfectly fine. The "inner" arrays will be null.
Inner dimensions do not have to be specified. This is legal in Java:
Object[][] arr = new Object[n][];
This creates an array of n elements, where each element has type Object[]. Since you did not specify an inner dimension, those n elements are all initialized to null. You can then assign any Object[] you want to any of those n array elements.
For higher-dimensional arrays, the rule (if you don't have an initializer) is that you can say new T followed by one or more specified dimensions ([some-value]), followed by zero or more [] for unspecified dimensions. You can't have [] followed by [value].
Related
What grabbed my attention, which I cannot explain to myself, is a thought about this well known code:
String[] str = new String[]{"a","b","c"};
Is new String[] a cast? If it is, why do we use new and no brackets? We would cast as in:
float i = (float) 3;
It also seem not to be a constructor, because then we would use it like a function call (e.g new String[](...)).
So what kind of syntax is it, and do we have more of that kind in Java?
This syntax is an example of an 10.6. Array Initializer as part of an 15.10.1. Array Creation Expression.
An array initializer may be specified in a field declaration (§8.3, §9.3) or local variable declaration (§14.4), or as part of an array creation expression (§15.10.1), to create an array and provide some initial values.
new String[]
is an array creation expression and
{"a","b","c"}
is an array initializer.
Since there are no dimension expression in your array creation expression (i.e. nothing inside the square brackets), there must be an array initializer:
If there are no dimension expressions, then there must be an array initializer.
A newly allocated array will be initialized with the values provided by the array initializer as described in §10.6.
It's called an Array Initializer, and its sole purpose, as the name suggests, is to initialize arrays.
The syntax is related to the array initializer:
An array initializer may be specified in a field declaration (§8.3, §9.3) or local variable declaration (§14.4), or as part of an array creation expression (§15.10.1), to create an array and provide some initial values.
Basically you not only create the array, but also initialize all its fields in the same instruction.
It is not a cast.
Note that the code:
String[] str = new String[]{"a","b","c"};
is a single command to create and initialize the array but it is also possible to use a less verbose version:
String[] str = {"a","b","c"};
Arrays can be created in multiple ways like below, and you are using the second one which is called the Array Initializer where you create the array while also initializing it.
int[] abc = new int[3]; // This means an array of integers with size 3 is created.
int[] def = new int[]{1,2,3}; // This means an array of integers with size 3 is created and also initialized with the values 1, 2 and 3.
In the second statement, I am creating an array of integers with the elements as 1, 2 and 3 where the size is implicitly 3.
So, in your case String[] str = new String[]{"a","b","c"}; , this statement is creating an array of String values with elements "a", "b" and "c" with the implicit size of the array being 3 due to the 3 elements which it is initialized with.
I was trying to allocate an Integer array for 100 items, why this declaration isn't valid in Java?
Integer[100] intArr1; ----- (1)
Whereas this is valid:
Integer[] intArr; ----- (2)
As (2) is valid, how much memory does it occupy? Can anyone help to explain a bit.
There are some questions in SO which resemble my question, however they are not the same, and I did look in SO before asking this question.
The first one isn't valid because that's not proper Java syntax.
The second one occupies 0 memory, as you haven't created an array. Only a reference to an array, with the reference being null.
You need a new Integer[100] there to actually create the array object.
You are mixing two different things.
One thing is the type of variable. In your case, you want to say "the type of variable intArr is array of Integers", which is this code Integer[] intArr;
In variable, which type is array of Integers you can put any array of Integers you like, no matter the size, therefore you cannot pre-defined it.
The second thing is assign to a variable.
Integer[] intArr = new Integer[10];
To initialise an array with 100 items you write:
Integer intArr1[] = new Integer[100];
Your second line of code just declares a variable, there is no size declared.
When you declare an array, you don't give it a length. You only give it a length when you initialise it.
This is just a declaration:
int[] myArray;
If you want to initialize it with an array of length 100, you do this:
myArray = new int[100];
An uninitialised array is null by default, or inaccessible if it is in a local scope.
for example: why this statement long[] n= new long[]; is wrong but this statement
long[][] n= new long[1][]; is right? How does the memory know how much memory needs to be assigned to the object in the second statement?
How does the memory know how much memory needs to be assigned to the object in the second statement?
Two things to remember here to figure out what's going on:
2D Java arrays aren't square, they're arrays of arrays.
You specify the size of an array when it's created.
So in this example, you're creating an array of longs (of size 1) to hold another array of longs - but you're not yet creating the second array (so you don't need to specify how large it will be.) In effect, the first array provides an empty "slot" (or slots if the outer array is longer than 1) for the inner array(s) to sit in - but the inner array(s) haven't yet been created, so their size doesn't need to be specified.
It doesn't just create an array of arbitrary length at all, it simply doesn't create any inner arrays.
You can perhaps see this more clearly if you try to access or store a long in the 2D array:
long[][] x = new long[2][];
x[0][0] = 7;
...will produce a NullPointerException (on the second line), because there is no inner array there to access.
In the first example that doesn't compile, you're trying to actually create an array of longs, but not giving it a dimension, hence the error.
when you write this - long[][] n= new long[1][];
you are creating array of arrays of long but you are not actually initializing those arrays right now
So if you do n[0] == null it will return true
that way you are free to initialize new array in any point of time later-
n[0] = new long[10];
So the point is - you need to provide size while initializing your array , that is why long[] n= new long[]; is wrong
Ok, so here's a small problem I'm facing - is there an easy way in Java to cast
ArrayList<Object[]> array;
to
Object[][] data;
?
Object[][] data=array.toArray();
The Object[]'s inside are treated as a type of object themselves. They then are put into their own array, leading to an array of array objects of objects, or simply a two-dimensional array.
Casting is not the solution you are looking for. Casting would essentially allow you to use a method that you cast to a specific class type. An example of a cast:
(((ClassA)classB).method())
So a returned value can be placed inside of a ClassA object from the instantiated classB object that contains method().
What you are wanting to do on the other hand is create a multidimensional array or a 2D array. This is essentially an array of arrays, where arrayA[i] = arrayB[];
For example:
Object[] objectArray = new Object[5];
Object[][] = objectArray2D = new Object[][];
objectArray2D[i] = objectArray;
Here is a point to your question though, if you create a multidimensional array, why would you feed it only one array instance. Essentially what you would create in the above example is an array inside of an array, and since you will be giving it only 1 array indexing of all the objects inside the array would be the same as if you had the one array, but with one additional placement. Let me explain:
objectArray[0] == the object you placed on the first slot of objectArray
while objectArray2D[0][0] == the exact same object as the object in objectArray[0]
You are not receiving any advantage by using a multidimensional array for one array. If you were to ask the 2D array for the index [1][0] you would receive an out of bounds exception.
Lastly, I would suggest that you create a specific form of array, such as int[], or string[]. The problem with a Object[] array is that you can store anything that is considered an Object into the array, allowing for a potential cluster of different types of Objects inside one array. Example you could have a objectArray[0] = int 1; and objectArray[1] = String one; Unless you want to be very specific in the array use, it might be better to use one Object type as the array.
In any case the final solution to do exactly what you are wanting to do is as follows:
ArrayList<Object[]> array;
Object[][] data;
public void changeToAnArray(ArrayList<Object[]> array, Object[][] data)
{
this.array = array.toArray();
this.data[0] = array;
}
Also due note the point of an ArrayList, is to have a 2D array in essence without having to parse the indexes.
Please anyone feel free to correct on the parts I am wrong on << still learning.
Is it possible (i am sure it is) and not too complicated to make dynamic multidimensional arrays which would increase dimension if needed?
// Array[] 1 has 2 dimensions
if(blah=blah)
{
Array[] 1 gets second dimension and is now Array[][]
}
No, it is not possible: the number of dimensions ofn an array is a property of the array's type, not of the array object, so you cannot do this with built-in Java arrays.
In order to emulate an array that can change the number of dimensions at runtime you would need to build your own class. You can base that class on an array or an ArrayList, but there would be one limitation: you would not be able to use subscript operators on your emulated array.
There is also the "ugly" solution: you can store your array without a type - essentially, as a typeless Object. You can assign arrays with any number of dimension to a variable of type Object, like this:
Object a = new int[10];
a = new int[10][2];
a = new int[10][2][5];
The catch is that you cannot access elements of such array without performing a cast:
a[2][1][0] = 7; // Will not compile
This will compile and work, but the construct is rather unreadable:
((int[][][])a)[2][1][0] = 7;
Also note that the prior content of the array will be lost on reassignment, unless you make a copy of it.