如何在Java中以编程方式访问多维数组



假设我们有一个多维数组,并且维数只有在运行时才知道。假设我们有一个整数个数的索引

如何应用索引数组,以便访问数组的元素?

假设:

int [] indices = new int { 2, 7, 3, ... , 4}; // indices of some element
int X = indices.length; // number of dimensions
Object array = .... // multidimensional array with number of dimensions X
...

我想从array中获取索引indices所寻址的元素。

更新2

我基于递归编写了以下代码:

package tests;
import java.util.Arrays;
public class Try_Multidimensional {
    private static int element;
    public static int[] tail(int[] indices) {
        return Arrays.copyOfRange(indices, 1, indices.length);
    }

    public static Object[] createArray(int ... sizes) {
        Object[] ans = new Object[sizes[0]];
        if( sizes.length == 1 ) {
            for(int i=0; i<ans.length; ++i ) {
                ans[i] = element++;
            }
        }
        else {
            for(int i=0; i<ans.length; ++i) {
                ans[i] = createArray(tail(sizes)); 
            }
        }
        return ans;
    }
    public static Object accessElement(Object object, int ... indices) {
        if( object instanceof Object[] ) {
            Object[] array = (Object[]) object;
            return accessElement(array[indices[0]], tail(indices));
        }
        else {
            return object;
        }
    }
    public static void main(String[] args) {
        element = 0;
        Object array = createArray(4, 5, 12, 7);
        System.out.println(accessElement(array, 0, 0, 0, 0));
        System.out.println(accessElement(array, 0, 0, 0, 1));
        System.out.println(accessElement(array, 1, 0, 10, 0));
        try {
            System.out.println(accessElement(array, 0, 5, 0, 1));
        }
        catch(Exception e) {
            System.out.println(e.toString());
        }
    System.out.println(4*5*12*7-1);
    System.out.println(accessElement(array, 3, 4, 11, 6));
    }
}

问题是:

1)有可靠的现成的方法从JDK和/或著名的库吗?

2)我使用Object。可以避免吗?我可以创建/访问内置或特定类型的可变维数组吗?使用Object的收益有多大?

int index(Object arrayToIndex, int... indices) {
    for (int i = 0; i < indices.length - 1; i++) {
        arrayToIndex = ((Object[]) arrayToIndex)[indices[i]];
    }
    return ((int[]) arrayToIndex)[indices[indices.length-1]];
}

循环遍历维度并索引每个维度,每次一个。最后一个维度的强制转换和特殊情况会很烦人,所以我建议将其包装在某种n维数组类中。(看起来有些选项已经存在了)

您可以发现每个维度的大小作为单独的数组(因为它们就是这样):

public void someMEthod(int[][][] matrix) {
    int d1 = matrix.length;
    int d2 = 0;
    int d3 = 0;
    if(d1 > 0) {
        d2 = matrix[0].length;
        if(d2 > 0) {
            d3 = matrix[0][0].length;
        }
    }
    System.out.println("Dimension 1 is " + d1);
    System.out.println("Dimension 2 is " + d2);
    System.out.println("Dimension 3 is " + d3);
}

我发现了一种使用反射的有趣方法。这只是我拼凑的一些代码,但你可以把它包装在一个类中,让它看起来更漂亮。

// build and fill an array to the given depth
public static Object[] constructArray(Object[] array, int depth) {
    if(depth == 0)
        return null;
    for(int i=0;i<array.length;i++) {
        Array.set(array, i, constructArray(new Object[array.length], depth-1));
    }
    return array;
}
// sets a value in the multi dimensional array using the indicies
public static void setArrayUsingIndecies(Object array, int[] indicies, Object value) {
    if(indicies.length == 0)
        return;
    for(int i=0;i<indicies.length-1;i++) {
        array = Array.get(array, indicies[i]);
    }
    Array.set(array, indicies[indicies.length-1], value);
}
// gets a value in the multi dimmensional array using the indicies
public static Object getArrayUsingIndecies(Object array, int[] indicies) {
    Object value = array;
    for(int i=0;i<indicies.length;i++) {
        value = Array.get(value, indicies[i]);
    }
    return value;
}

下面是一段示例代码

int numberOfDimmensions = 2;
Object array = constructArray(new Object[numberOfDimmensions], numberOfDimmensions);
int [] indices = new int [] { 0, 1 };
setArrayUsingIndecies(array, indices, "Hello");
System.out.println(getArrayUsingIndecies(array, indices)); // Hello
indices = new int [] { 0, 0 };
System.out.println(getArrayUsingIndecies(array, indices)); // null

是不是比我们想象的更简单?这个方法怎么样:

int [] indices = new int { 2, 7, 3, ... , 4}; // indices of some element
int X = indices.length; // number of dimensions
Object array = new Object[X].... // multidimensional array with number of dimensions X

然后:

Object myObject = array[indices[1]]  // myObject references the 7th element of array

你必须确保,虽然你的索引数组不包含一个数字大于索引的大小- 1。例如

indices = new int [5,4,3,2,1] // ok
indices = new int [6,4,3,2,1] // not ok, because you would access the 6th Element in an arry with length 5

相关内容

  • 没有找到相关文章

最新更新