Is it possible in Java to find the number of dimensions of an array with an \'a priori\' unknown number of dimensions? That is, if one doesn\'t know the number of dimensions
Does anyone know if it is possible in Java to get the number of dimensions of an array with an 'a priori' unknown number of dimensions? That is, if one doesn't know the number of dimensions of a multidimensional matrix, how could it be retrieved, if possible?
I'm not quiet sure if I understood correctly what you are trying to accomplish. If you just want to know how many elements are there in array, Anubian's answer is correct. But what I understood is that you want to calculate number of dimensions of a given general array.
public class Test {
public static int getNumberOfDimensions(Class> type) {
if (type.getComponentType() == null) {
return 0;
} else {
return getNumberOfDimensions(type.getComponentType()) + 1;
}
}
public static void main(String[] args) {
System.out.println(getNumberOfDimensions(int[][][].class) == 3);
System.out.println(getNumberOfDimensions(int[][].class) == 2);
System.out.println(getNumberOfDimensions(int[][][][].class) == 4);
System.out.println(getNumberOfDimensions(int.class) == 0);
}
}
If that's not what are you looking for, I'd have a hint: there is a difference between a length and dimension.
Update: I think this is completely irrelevant to what we were asked, but Nicola asked me in the comments:
This works perfectly, but what about if the number of dimensions is defined at run-time (for instance the user has to input the desired amount of dimensions)? How you could define and initialize the array?
The solution lies in some light reflection-based hacking:
import java.lang.reflect.Array;
public class Test {
public static Class> getArrayType(Class> componentType, int dimensions) throws ClassNotFoundException {
if (dimensions == 0) {
return componentType;
}
String rawName = componentType.getName();
switch (rawName) {
case "byte": rawName = "B"; break;
case "char": rawName = "C"; break;
case "double": rawName = "D"; break;
case "float": rawName = "F"; break;
case "int": rawName = "I"; break;
case "long": rawName = "J"; break;
case "short": rawName = "S"; break;
case "boolean": rawName = "Z"; break;
default:
rawName = "L" + rawName + ";";
break;
}
for (int i = 0; i < dimensions; i++) {
rawName = "[" + rawName;
}
return Class.forName(rawName);
}
public static Object createArray(Class> componentType, int dimensions, int length) throws NegativeArraySizeException, ClassNotFoundException {
if (dimensions == 0) {
return null;
}
Object array = Array.newInstance(getArrayType(componentType, dimensions - 1), length);
for (int i = 0; i < length; i++) {
Array.set(array, i, createArray(componentType, dimensions - 1, length));
}
return array;
}
public static void main(String[] args) throws ClassNotFoundException {
Object object = createArray(Integer.class, 3, 10);
System.out.println(object.getClass());
}
}
The trick is to construct a Class for N-dimensional array using a given component type. We can do that if we know how class names are stored on the lowest level. Rest of the code is just a simple not-interesting recursion.