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 of a multidimensional matrix, how could it be retrieved, if possible?
-
1Do you mean how to tell an `int[]` apart from an `int[][][][][]`? – azurefrog Apr 22 '14 at 21:56
-
2How are you receiving this array, if you don't know its type? Simply as `Object`? – David Conrad Apr 22 '14 at 22:07
-
Right! You could receive it as an Object or as some variable user input. The case is, the true number of dimensions is unknown. (Don't confuse it with the number of elements in any row, column, or more complex geometries/structures). My interest is in determining the number of diferent dimensions in a matrix/hypermatrix. – shirowww Apr 23 '14 at 00:56
-
To clarify: the number of dimensions is unknown for us, but obviously, it has to be known in some other environment or context (user point of view, for example). The important point is, we receive it with no knowledge of its number of dimensions, even they could be unknown until runtime. How to determine it? Thanks! – shirowww Apr 23 '14 at 01:04
5 Answers
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.

- 1,285
- 1
- 10
- 23
-
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? – WoDoSc Apr 22 '14 at 22:18
-
I don't think this is what we were asked, but it'd be possible using reflection. – tzima Apr 22 '14 at 22:29
-
-
Ok, good point to use reflection to solve this issue. I'm not experienced in this field, but maybe reflection is not the most efficient way, but anyway from a theoretical and conceptual point of view it works. A possible improvement is to make the length parameter an array itself: with some little adaptation one could have the feature to define different size for each dimension. – WoDoSc Apr 22 '14 at 23:04
-
Yes, of course, but I guess it's something everyone would be able to change. BTW: I don't think there's an real use-case for arrays with unknown number of dimensions. I don't remember if I have ever used a three-dimensional array, now we are talking about N-dimensional array... It's whole a theoretical task with no real usage. But since it was asked, I answered. It's always fun to hack up some solution like this! – tzima Apr 22 '14 at 23:17
Assuming your matrix is called m:
You can get the number of columns by running
m.length;
With Java, multidimensional arrays are actually arrays of arrays. The number of rows is variable. Assuming i is an integer between 0 and m.length-1
you can do:
m[i].length;
To get the number of elements in the row.

- 13,426
- 6
- 53
- 75
-
1You're right, but you can not proceed with this approach indefinitely: suppose that you have a third or a fourth dimension... or even more complicated suppose you do not know how many are actually the dimensions (as stated in the question): an approach of this kind, 'hard-coded', in my opinion is not feasible – WoDoSc Apr 22 '14 at 22:13
The initial problem here is that you can't begin by saying something to the effect of:
int getNumDimensions(int[] array) { ... }
Because this would fail if theArray
was actually an int[][]
, int[][][]
, etc. But all arrays in Java are Object
subclasses, so this can work for any number of dimensions:
int getNumDimensions(Object array) {zz
if (array instanceof Object[]) {
// array has at least 2 dimensions (e.g. int[][])
return getNumDimensions(((Object[]) array)[0]) + 1;
}
if (array.getClass().isArray()) {
// array is, by process of elimination, one-dimensional
return 1;
}
return 0;
}
Edit: I've tried my hand at a non-recursive solution for those crazy million-dimensional arrays!
int getNumDimensions(Object array) {
Object tmp = array;
int nDimensions = 0;
while (True) {
if (array instanceof Object[]) {
// tmp has at least 2 dimensions (e.g. int[][])
tmp = ((Object[]) array)[0];
}
else if (tmp.getClass().isArray()) {
// tmp is, by process of elimination, one-dimensional
return nDimensions + 1;
}
nDimensions++;
}
}

- 2,219
- 1
- 18
- 32
-
I don't have the JDK available at the moment, so please let me know if this code fails. – SimonT Apr 22 '14 at 22:24
-
There are some compile and logic errors in the code. I've edited to correct these. – Tim Jul 07 '20 at 20:22
-
I've also pointed out in the edited code, if any dimension is size 0, there is no way to continue to count any dimensions after that one. In fact, if the array was allocated via the ```multianewarray```, any further dimensions are not even allocated. According to JVM Spec, ```If any count value is zero, no subsequent dimensions are allocated.``` – Tim Jul 07 '20 at 20:26
-
Also worth noting, since the implementation only checks index 0, the result for jagged arrays may be different than expected. Consider ```new Object[]{new int[2], new int[3][1][2]}```. The result will be 2 but if the implementation had checked index 1 from the Object[], it would have computed 4. But perhaps in that case, asking for the number of dimensions doesn't even make sense! – Tim Jul 07 '20 at 20:41
What I can suggest you is to manage this issue by using an array with only one dimension. Suppose to have N dimensions of sizes:
Then you can define the size of your array as:
int size = S_0*S_1*...*S_N-1;
Then you will initialize it, for instance for an array of integers:
int[] array = new int[size];
Then to refer to an item of the array (to read or write it), you have N indexes (because of N dimensions):
What you need now is a way to transform this N indexes, in one single value that can be used as an index in the one-dimensional array, the generic formula is:
Basically this formula 'skips' the correct number of previous dimensions and points to the right location. This formula can be simply implemented in methods like
int read(int[] array, int[] indexes);
void write(int[] array, int[] indexes, int values);
in order to keep the code readable. You may also implement this technique using a generic type, so the methods might work for any type.

- 2,598
- 1
- 13
- 26
-
A viable alternative, although it's not usable for determining what the asker's looking for. – SimonT Apr 22 '14 at 22:29
-
I see what you mean, by my point is: how can you ever end up in a situation such as that described in the question, where you obtain an array (for example as a return value from a method, or a method parameter), without defining in the code the number of dimensions? I do not see how you could have a situation like that (in C would be different, by using a pointer int* array, which can point to an array of any dimension, but here we are in Java), so probably the asker himself had to implement a way to handle this problem. – WoDoSc Apr 22 '14 at 22:34
Just look at its dynamic type either by looking directly in your code where it is initialized or by calling its class and examining its reflected attributes.

- 2,541
- 1
- 14
- 11
-
-
a.getClass() will return the number of dimensions as the name of the class e.g. an int[][] would return a name of "class [[I". If you need this dynamically however, then you should look at the component type as Tomas has showed. – isak gilbert Apr 22 '14 at 22:27