假设我们有一个多维数组,并且维数只有在运行时才知道。假设我们有一个整数个数的索引
如何应用索引数组,以便访问数组的元素?
假设:
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