Remove empty dimension from multi-dimensional array - java

I have this type of array float[1][1][54][54]. If it possible to cast this array to float[54][54]? Maybe it`s possible to remove two first empty dimensions?

You can't cast it, but you can just assign the inner array to a new variable:
float[][][][] arr1 = new float[1][1][54][54];
float[][] arr2 = arr1[0][0];
Note that although they're separate variables, they actually share a reference to the same inner array, so they can't be modified separately.

Related

Why is declaring an empty array of non-empty array(s) legal in Java?

Curious why declaring an empty array of non-emtpy array(s) is legal in Java:
int[][] array = new int[0][1];
System.out.println(array[][0]); //won't compile.
System.out.println(array[0][0]) //triggers an out of bounds exception.
P.S. I have read the related question on zero-size arrays: Why does Java allow arrays of size 0?
Is this for the same reason?
An int[][] array is an array whose elements are int[] (i.e. its elements are arrays of int).
Just like you are allowed to define an empty array of int elements:
int[] empty = new int[0];
or an empty array of String elements:
String[] empty = new String[0];
You are also allowed to define an empty array of int[1] elements:
int[][] empty = new int[0][1];
Perhaps it's the syntax that is somewhat confusing here.
If it was
int[][] empty = new (int[1])[0]
it would be clearer that you are defining an empty array whose element type is int[1].
However, since the number in the first square brackets represents the number of elements in the outer array, new int[1][0] does not represent an empty array, but an array of a single element (whose single element is an empty int array).
It is legal to define empty arrays in general, no matter what it contains. Thus, it is also legal to have an empty array containing non empty arrays.
Mathematically (group theory) speaking, empty arrays are not only legal, but necessary, since they represent the zero (or neutral) element of array concatenation operation. This also makes it useful for programming (see the example below).
In your example you basically probe, if it is ok to access elements of an empty array. This is of course not legal, since there are none. However you can do:
int[][] array = new int[0][1];
System.out.println(array.length);
With reference to my own example above, a more useful case is:
int[][] array1 = new int[1][1];
int[][] array2 = new int[0][1];
array1[0][0] = 1;
int [][] concat = Stream
.concat(Arrays.stream(array1), Arrays.stream(array2))
.toArray(int[][]::new);
System.out.println(Arrays.deepToString(concat));
Thus empty arrays allow to for "good" code, without ifs to exclude, illegal cases, which actually are totally fine.
as per your declaration:
int[][] array = new int[0][1];
you have declared 2D array where length of the array is 0
it means it will not be able to contain any element thats why
System.out.println(array[0][0]). array[0][0] is out of bound index error
An array dimension of zero means the array has zero elements. Hence there is no element at index 0 (zero).
When you declare a two-dimensional array in Java, the first array dimension is mandatory.
Refer to chapter 10 of the Java Language Specification.

Changing the number of dimensions an Java array has

Is there a way of changing the number of dimensions an array has, i.e making this
int[][] i = new int[3][3];
but using it like this
getArray(i); //where getArray only accepts one dimensional arrays
?
You cannot change the number of dimensions in a Java array or array type.
But you can make use of the fact that a Java array is an object ... and subtyping .. and declare a getArray method like this:
Object getArray(Object[], ...) { .... }
You can call this method on a int[][] instance, but a runtime typecast is needed to cast the result to an int[].
For example:
Object getArray(Object[] array, int i) { return array[i]; }
int[][] big = new int[3][3];
int[] slice = (int[]) getArray(big, 0);
On the other hand, if you are really asking about how to flatten a multi-dimensional array into a 1-D array, the getArray method needs to allocate a new array, fill it from the original and return it.
Note you would be returning a brand new array that is unconnected to the original one. And copying an N x N .... x N array is expensive.
For more details: Flatten nested arrays in java
Java is statically-typed language. This means that you cannot change a variable's type at runtime. But in this particular case you can simply use the following invocation:
getArray(i[2]); // put anything between 0 and (outerArrayLength-1) instead of 2 here

How to create an array of objects of a specific class type

I have a function that returns an Object. The Object can contain an array of primatives or an array of objects. In C# I can create an empty array of objects or primatives using code like:
Array values = Array.CreateInstance(/*Type*/type, /*int*/length);
Is there an equivalent in Java?
How to create an array of objects of a specific class type
Test[] tests = new Test[length] ;
And if you want to have a mix up of Primitives and Objects, though it is not suggestable, If you want to mix primitives with Objects
Object[] objs = new Object[length];
That allows you to both primitives(in form of wrappers) and normal Objects together.
If you have a class called Test of your own, you can create an array of Test's like
Note that until you initialise the elements in that array, they have null as their value.
Assuming you only know the element type at execution time, I think you're looking for Array.newInstance.
Object intArray = Array.newInstance(int.class, 10);
Object stringArray = Array.newInstance(String.class, 10);
(That will create an int[] and a String[] respectively.)
Object[] array = new Object[length];
Or with your own type:
MyType[] array = new MyType[length];

Adding values to already initialized object array in Java?

I'm developing for the Android platform and, to simplify the question, I'm using pseudo-names for the entities.
I have an object array stuff[] of the class StuffClass[].
StuffClass stuff[]={
new StuffClass(Argument, argument, argument),
new StuffClass(argument, argument, argument)
};
I have an activity returning a result of three arguments that I want to then use to add a new object to stuff[]. I've done so as follows:
stuff[stuff.length]=new StuffClass(argument, argument, argument);
and I get ArrayOutOfBounds (Figured that would happen).
So how might I go about creating a new object in the stuff[] array?
Arrays are static you can't change size without creating a new one before. Instead of that you can use a dynamic data structure such as an ArrayList
Example:
List<MyType> objects = new ArrayList<>();
objects.add(new MyType());
Here you forget about array size.
Array in Java is little bit special, it's length is fixed when it's initialized, you can not extend it later on.
What you can do is to create a new array, and use System.arraycopy to generate a new array, here's the sample code:
String[] arr1 = new String[]{"a", "b"};
String[] arr2 = new String[3];
System.arraycopy(arr1, 0, arr2, 0, 2);
arr2[2] = "c";
You cannot increase the size of an existing array. Once it's created, the size of the array is fixed.
You will need to create another bigger array and copy the items from the old array to the new array.
A better alternative is to use an ArrayList. When you add items to an ArrayList, the capacity will grow behind the scenes if needed; you don't have to worry about increasing the size.
you can use the ArrayList to do this
arraylist.add(object);
in java arrays are fixed length. you need to initialise them with the desired length.
Consider using a Collection such as ArrayList which will handle everything for you.
List<StuffClass> myList = new ArrayList<>();
myList.add(...);
Lists support similar behaviour to arrays ie:
myList.set(i, elem);
myArray[i] = elem;
elem = myList.get(i);
elem = myArray[i];
len = myList.size();
len = myArray.length;
You can then convert the list to an array.
StuffClass[] myArray = myList.toArray(new StuffClass[myList.size()]);
If you don't want to use lists consider using System.arrayCopy to create a new array with more elements.
read here for a good description.

Can someone break down this line so I can understand it?

I'm having trouble understanding how an array of ArrayLists is initialized in Java, can someone explain what's going on in this line of code?
edges = (ArrayList<Integer>[]) new ArrayList[nodeCount + 1];
Let's break it space-by-space.
edges is a variable of type ArrayList<Integer>[]
= is the assign operator which assignes the right-hand to the left-hand
(ArrayList<Integer>[]) is a cast of a variable to the type.
new ArrayList[nodeCount + 1] means we allocate space for an array of ArrayList with nodeCount+1 unknown elements.
This is a very bad way of initializing an array. What it does is it creates an array and makes the elements into Integers.
An alternative:
edges = new ArrayList<Integer>(nodeCount+1);
Explanation: The ArrayList class has a constructor which can specify its length*, this is what I use here.
Note: According to #Rohit Jain, it doesn't specify the length, but the initial capacity.
You cannot create an array whose component type is parameterized type. It's not type safe. Although you can create an array whose component type is raw type, but that won't be type safe either. Consider the following example:
List<Integer>[] list = null; // Declaration is OK
list = new ArrayList<Integer>[5]; // Compiler error: Generic array creation
list = new ArrayList[5]; // Compiles fine. But not safe. Gives warning
Suppose you created an array of raw types. Let's see what can be the implication:
List<Integer>[] list = new ArrayList[10]; // Not type safe
Object[] objArr = list; // We can assign List<Integer>[] to Object[]
// We can add even ArrayList<String> in Object[]
// This will successfully compile, and run.
objArr[0] = new ArrayList<String>() {
{
add("rohit"); add("jain");
}
};
// Here's the problem. It will compile fine, but at runtime will throw
// ClassCastException
Integer val = list[0].get(0);
Alternative is create a List of List:
List<List<Integer>> edges = new ArrayList<List<Integer>>();
Suggested Read: -
Angelika Langer Generic FAQs:
Can I create an array whose component type is a concrete parameterized type?
Can I declare a reference variable of an array type whose component type is a concrete parameterized type?
In the above line you are creating an array of ArrayList, you could replace ArrayList by a more simple type to help you to understand, e.g. an array of String:
edges = (String[]) new String[nodeCount + 1];
nodeCount + 1 corresponds to size of the array. The array can't have more than this number of elements.
Note that using an array of a parametrized ArrayList is quite strange and prone to misunderstanding and errors. I would use a List<List<Integer>> here, e.g.:
edges = new ArrayList<List<Integer>>();
this line defines an array, like any other array out there: exampe new Object[0], new String[0], ...
and just like any other array, the values will be initiated with the null value. for primitive types is that '0', for objects/classes is that null.
so you should initiate the different arraylists before using it like:
edges = new ArrayList<Integer>[nodeCount + 1];
for(int i=0; i<edges.length; i++){
edges[i] = new ArrayList<Integer>();
}
This does not initialize an ArrayList -- it initializes an array of ArrayLists:
new ArrayList[nodeCount + 1] = create an array of ArrayList objects with nodeCount + 1 slots
(ArrayList<Integer>[]) = cast it to an "array of ArrayList objects which in turn may only contain Integer objects". This is needed because the array declaration syntax of java apparently can't handle generics (just tried it -- I never needed this before).
It could be a misunderstanding, and the writer actually wanted to initialize one ArrayList with a capacity of nodeCount+ 1. The correct code for that would be
edges = new ArrayList<Integer>(nodeCount + 1);
Actually the capacity parameter is just an optimization, since ArrayList objects grow automatically as needed. But if you already know how many entries you need, the List can be created with enough capacity from the start.
new ArrayList[nodeCount + 1]
create a new array of ArrayList, its length is nodeCount + 1;
then
(ArrayList<Integer>[])
is a cast operation, it casts the array you just created into an array of ArrayList<Integer>

Categories