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.
Related
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.
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].
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
This question already has answers here:
Java dynamic array sizes?
(19 answers)
Closed 9 years ago.
I know you can't dynamically expand a normal array but is this a valid way of doing it?
public int size = 0;
public String[] OrigArray = new String[size+1];
public void expand(){
String[] tempArray = new String[size+1];
tempArray = (String[])OrigArray.clone();
OrigArray = new String[size+1];
OrigArray = (String[])tempArray.clone();
size++;
}
I'm aware of much better methods than trying to use a normal array but I'd like to figure this for just using a normal array first.
My desire is that it starts off with OrigArray being 0+1 (so 1) and when expand() is called the new tempArray is made that is the same size as the OrigArray and this then holds OrigArray while OrigArray is declared again with size+1 then the tempArray is copied back to the newly sized OrigArray. This makes sense to me, but I keep getting out of bound exception?
The method does not change the value of OrigArray; all it does is store a clone of a clone in it, so in effect the value isn't changed.
I think what you want is this:
public void expand() {
String[] newArray = new String[OrigArray.length + 1];
System.arraycopy(OrigArray, 0, newArray, 0, OrigArray.length);
//an alternative to using System.arraycopy would be a for-loop:
// for(int i = 0; i < OrigArray.length; i++)
// newArray[i] = OrigArray[i];
OrigArray = newArray;
}
This creates an array that has a size 1 greater than OrigArray, copies the content of OrigArray into it and assigns that array to OrigArray. Unless you want to remember how many times expand() has been called, there shouldn't be a reason to have the variable size.
EDIT: If what you really want is to know a way to sensibly implement the functionality you asked for, you can go with what #Óscar López said and use ArrayList.
What you're trying to accomplish by hand, it's pretty much what ArrayList does for you - use that class, instead.
Under the hood, ArrayList uses an Object[] for storing items, under a certain capacity constraint. When the array is filled (as new items are added), a new array with doubled size is created and all the items in the original array are copied in it. All this happens automatically, and it's transparent for the programmer.
Given that in the sample code you're storing an array of objects (Strings), there'll be little difference in performance if you use an ArrayList for storing them, so there's no real reason to reinvent the wheel!
No, that is not a valid way to do it. What you are doing is actually
First create a new larger array
Throw away the newly created array and copy the original array
Create year another new array with larger size
Throw away the newly created array and clone the already cloned array again
For non primitive types I think you want to use the ArrayList
However, if you want to build this for primitive types, this is how you would do it
public int size = 0;
public int[] origArray = new int[size+1];
public void expand(){
int[] tempArray = new int[size+1];
System.arrayCopy(origArray, 0, tempArray, 0, size);
origArray = tempArray;
size++;
}
You probably want to hide the data behind accessors (get...() methods) and you do not want to just expand the array by one element at a time, creating and copying arrays is costly.
This:
OrigArray = new String[size+1];
OrigArray = (String[])tempArray.clone();
is essentially equivalent to just this:
OrigArray = (String[])tempArray.clone();
in that the second assignment completely supersedes the first. OrigArray will end up having the same size as tempArray, and therefore the same size that it originally had.
If you want to copy elements into an existing array, you have to either write a loop, or else use java.lang.System.arrayCopy(...) which handles the loop for you; but calling clone() on an array will always create a new array, so will not help.
Your method won't work because clone() will just reassign the array to the original size. I would recommend using
System.arraycopy(OrigArray, 0, tempArray, 0, OrigArray.length);
instead.
Also, the most efficient way of doing this would be to use an ArrayList, since they implement practically the same thing, but clean up your code a lot.
The only problem is when you need to get a regular array of the value's type, then you would have to do this:
String[] asArr = new String[OrigArray.length];
for(int i = 0; i < OrigArray.length; i++)
asArr[i] = OrigArray.get(i);
Here is the Javadoc for ArrayList:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html
Take a look at System.arraycopy -- it copies one array to the other (you can also do this yourself in a loop, though arraycopy is a bit faster). So the general pattern is to create a new array that's bigger than the first, then copy the first's elements into the bigger one, and then update your field/variable to point to this new, bigger array.
Constantly constructing and destructing objects in memory is costly and slow. I would write a class that stores a little extra space (maybe 3-5 extra items), similarly to how List works, and when querying the size only output the used spaces and only expand when exceeding this buffer space. This can greatly improve performance.
I was wondering about the implementation of length of a Java Array. I know that using arrayName.length gives us the number of elements in the array, but was wondering if this is a method / function or it is just a data member of Array?
I guess it must be a data member as we do not use parenthesis() when invoking it. But if it is a data member how/when is the value of this length assigned/computed?
According to the Java Language Specification (specifically §10.7 Array Members) it is a field:
The public final field length, which contains the number of components of the array (length may be positive or zero).
Internally the value is probably stored somewhere in the object header, but that is an implementation detail and depends on the concrete JVM implementation.
The HotSpot VM (the one in the popular Oracle (formerly Sun) JRE/JDK) stores the size in the object-header:
[...] arrays have a third header field, for the array size.
You're correct, length is a data member, not a method.
From the Arrays tutorial:
The length of an array is established when the array is created. After creation, its length is fixed.
If you have an array of a known type or is a subclass of Object[] you can cast the array first.
Object array = new ????[n];
Object[] array2 = (Object[]) array;
System.out.println(array2.length);
or
Object array = new char[n];
char[] array2 = (char[]) array;
System.out.println(array2.length);
However if you have no idea what type of array it is you can use Array.getLength(Object);
System.out.println(Array.getLength(new boolean[4]);
System.out.println(Array.getLength(new int[5]);
System.out.println(Array.getLength(new String[6]);
Yes, it should be a field. And I think this value is assigned when you create your array (you have to choose the length of array while creating, for example: int[] a = new int[5];).
I believe its just a property as you access it as a property.
String[] s = new String[]{"abc","def","ghi"}
System.out.println(s.length)
returns 3
if it was a method then you would call s.length() right?
From the JLS:
The array's length is available as a
final instance variable length
And:
Once an array object is created, its
length never changes. To make an array
variable refer to an array of
different length, a reference to a
different array must be assigned to
the variable.
And arrays are implemented in the JVM. You may want to look at the VM Spec for more info.
It is a public final field for the array type. You can refer to the document below:
http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.7
Every array in java is considered as an object. The public final length is the data member which contains the number of components of the array (length may be positive or zero)
Java arrays, like C++ arrays, have the fixed length that after initializing it, you cannot change it. But, like class template vector - vector <T> - in C++ you can use Java class ArrayList that has many more utilities than Java arrays have.