3

Is there a possible way to create an array with a variable number of dimensions?

For example,

int x = 3;
// becomes
int[][][] array = new int[3][3][3];

//and
int y = 4;
//becomes
int[][][][] xray = new int[4][4][4][4];

Part of the reason my examples are so indirect is because I have no idea how one would do something like this.

If I have a variable I would like to create an array with the same number of dimensions as said variable

15
  • can you tell why you want to use that, so we can suggest you another approach ? Commented Feb 2, 2017 at 2:06
  • see this stackoverflow.com/questions/3104504/… Commented Feb 2, 2017 at 2:06
  • Can you explain better what do you want to know? The examples are very confusing Commented Feb 2, 2017 at 2:07
  • 1
    Can you show us the code which you imagine you would use if you had this ability? You might do better to use one of Java's collection classes. Commented Feb 2, 2017 at 2:11
  • 1
    you can't do this with Java, but that isn't to say its not a thing in other languages; en.wikipedia.org/wiki/Variable-length_array Commented Feb 2, 2017 at 3:11

4 Answers 4

5

You can't do this directly, but you can simulate it with a 1-dimensional array.

Suppose you have a 2-dimensional array with 3 rows and 4 columns. You could implement this as an array of 12 elements, and write a get routine to get the A[i,j] element like this:

int[] A = new int[12];

int get(int i, int j) {
    return A[4 * i + j];
}

Of course you could write a set method to set an element of the array in the same way.

Moving on to a 3-dimensional array whose dimensions are 3x4x5, you could do something similar:

int[] A = new int[60];

int get(int i, int j, int k) {
    return A[4*5*i + 5*j + k];
}

or a 4-dimensional 3x4x5x6 array:

int[] A = new int[360];

int get(int i, int j, int k, int m) {
    return A[4*5*6*i + 5*6*j + 6*k + m];
}

And so on... you should be able to see the pattern.

Once you've grasped that, it shouldn't be hard to write a class for an array that takes a variable number of dimensions. The get and set methods could take an int... parameter for a variable number of indexes, and the constructor could similarly take an int... to specify the dimensions. The class would have a private 1-dimensional array whose length is the product of all the dimensions. The get and set methods should check each index to make sure it's >= 0 and less than the corresponding dimension, and throw an exception otherwise.

This is how "true" multi-dimensional arrays are implemented under the hood in most languages that support them (Java is not one of those; it only has 1-dimensional arrays whose elements can be references to other 1-dimensional arrays). It's called "row-major order". See https://en.wikipedia.org/wiki/Row-_and_column-major_order for more information (including the generalized formula).

Sign up to request clarification or add additional context in comments.

Comments

1

Short answer you can't. Reason: there is no instance in the world of maths where such a construct could be optimum for anything so the Prophets (K&R and all the good ppl who invent code) left such to the developer who needs it.

But here is my 2 cents: I assume you want to initialize your engine...

engine.init(n);

where n is your dimension. Then be able to put and get things from it.

engine.get(a1,a2,a3,...);
engine.put(val,a1,a2,a3...);

Consider a class like this

public class Engine{
private HashMap<Integer[],Object> storage;
private int dimension=1;
private set<integer[]> keys;
public void init(int n){
dimension=n;
//other initialization task;
}

public Object get(int... a){//use var args
integer[] key=findInkeySet(a);
return storage.get(key);
}

public void put(Object val, int... a){
keys.add(a);
storage.put(a,val);
}
}

ofcause there is need for exception handling and all the other generic coding stuf

Comments

0

I try to make this , but return type is Object[] ^^"

public Object[] MakeArray(int s){
  ArrayList l = new ArrayList<>(Collections.nCopies(s, 0));
  for (int i = 1; i < s; i++)
    l = copy(l,s);
  return l.toArray();
}
public ArrayList copy (ArrayList l,int s){
    ArrayList<ArrayList> ret = new ArrayList<>(s);
    for (int i = 0; i < s; i++) 
        ret.add(new ArrayList(l));
    return ret;
}

Arrays.toString(MakeArray(2)) = "[[0, 0], [0, 0]]"
Arrays.toString(MakeArray(3)) = "[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]"

Comments

0
public Object createMultidimensionalArray(int dimLength){
    int[] lengths = new int[dimLength];
    for(int i = 0; i < dimLength; i++)
        lengths[i] = dimLength;
    return Array.newInstance(int.class, lengths);
}

Usage example:

int[][][] array3D = (int[][][]) createMultidimensionalArray(3);
System.out.println(Arrays.deepToString(array3D));

Output:

[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]

Explanation:

The function Array.newInstance(Class<?> componentType, int... dimensions) takes as input the wanted array type and lengths of all dimensions.

dimensions is an array that tells the function what size each dimension should be. To get a 4x4x4x4 array, the following code works:

int[] dimensions = {4, 4, 4, 4};
Object arrObj = Array.newInstance(int.class, dimensions);
int[][][][] arr = (int[][][][]) arrObj;

Array.newInstance(...) returns an Object which can be easily converted to the correct type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.