One approach would be to define your own class to represent an array with variable dimensions. Implementing the class isn't trivial, though.
I'd take advantage of Java's "variable arity" methods:
public class DynamicDimensionArray {
public DynamicDimensionArray(int... dimension) {
// code
}
This lets callers do things like
DynamicDimensionArray vector = new DynamicDimensionArray(10); // one-dimensional
DynamicDimensionArray matrix = new DynamicDimensionArray(3, 5); // two-dimensional
DynamicDimensionArray fiveDim = new DynamicDimensionArray(2, 3, 2, 10, 4);
// five-dimensional
Inside the constructor, dimension
is actually treated as an int[]
. So dimension.length
gives you the number of dimensions.
So how would you implement the class? I think the simplest way (which isn't really that simple) is to have private variable that is a 1-dimensional array of your type (let's assume it's a double
). The number of elements is obtained by multiplying the elements in the dimension
:
private double[] data;
public DynamicDimensionArray(int... dimension) {
int totalElements = 1;
for (int dim : dimension) {
totalElements *= dim;
}
data = new double[totalElements];
}
Then implementing the rest of the class depends on what operations you want to support. You might want a getElement
method to get one element of the array:
public double getElement(int... index) {
// ???
}
As before, index
will be an int[]
inside the method. You'd check to make sure the length matches the length of the original dimension
and throw an exception if not. The trick will be converting the indexes to an index you can use in your one-dimensional data
. The basic formula (assuming all indexes are 0-relative) looks like this:
If it's a 1-dimensional array with dimensions d0, and the indexes are i0, the index into data
is just i0.
If it's a 2-dimensional array with dimensions (d1, d0), and the indexes are (i1, i0), the index into data
is i1d0 + i0.
If it's a 3-dimensional array with dimensions (d2, d1, d0), and the indexes are (i2, i1, i0), the index into data
is i2d1d0 + i1d0 + i0.
And so on... you should be able to see the pattern.
Look up "row-major order" in Wikipedia for more information.
It's not trivial, though; so if you're limited to a small number of dimensions, such as 3, then you should consider Tim's comment that using a switch
might be OK.