[英]Array of arbitrary dimension as method parameter
我有一个简单的转换方法,用于从boolean
到int
的数组:
public static int[] convert1dToInt (boolean[] x) {
int la = x.length;
int[] y = new int[la];
for (int a = 0; a < la; a++) {
if (x[a]) {
y[a] = 1;
} else {
y[a] = 0;
}
}
return y;
}
现在我对二维数组有相同的方法:
public static int[][] convert2dToInt (boolean[][] x) {
int la = x.length;
int lb = x[0].length;
int[][] y = new int[la][lb];
for (int a = 0; a < la; a++) {
for (int b = 0; b < lb; b++) {
if (x[a][b]) {
y[a][b] = 1;
} else {
y[a][b] = 0;
}
}
}
return y;
}
如何在不编写所有方法的情况下,将这些方法推广到任意维度的数组?
这是可能的,但反射和递归都是不可避免的:
import java.lang.reflect.Array;
public class ArrayTransfer {
private static int getArrayDimension(Object array) {
Class<?> clazz = array.getClass();
int dimension = 0;
while (clazz.isArray()) {
clazz = clazz.getComponentType();
dimension += 1;
}
if (clazz != boolean.class) {
throw new IllegalArgumentException("Base array type not boolean");
}
return dimension;
}
// Transfers a boolean array of the specified dimension into an int
// array of the same dimension.
private static Object transferToIntArray(Object booleanArray, int dimension) {
if (booleanArray == null) {
return null;
}
// Determine the component type of the new array.
Class<?> componentType;
if (dimension == 1) {
componentType = int.class;
} else {
// We have a multidimensional array; the dimension of the component
// type is one less than the overall dimension. Creating the class
// of an array of an unknown dimension is slightly tricky: we do
// this by creating a 0 x 0 x ... x 0 array (with dimension - 1
// zeros) and then getting the class of this array. Handily for us,
// int arrays are initialised to all zero, so we can create one and
// use it straight away.
int[] allZeroDimensions = new int[dimension - 1];
componentType = Array.newInstance(int.class, allZeroDimensions).getClass();
}
// Create the new array.
int length = Array.getLength(booleanArray);
Object newArray = Array.newInstance(componentType, length);
// Transfer the elements, recursively if necessary.
for (int i = 0; i < length; ++i) {
if (dimension == 1) {
Boolean value = (Boolean)Array.get(booleanArray, i);
Array.set(newArray, i, (value.booleanValue()) ? 1 : 0);
}
else {
Object oldChildArray = Array.get(booleanArray, i);
Object newChildArray = transferToIntArray(oldChildArray, dimension - 1);
Array.set(newArray, i, newChildArray);
}
}
return newArray;
}
// Transfers a boolean array of some dimension into an int
// array of the same dimension.
public static Object transferToIntArray(Object booleanArray) {
if (booleanArray == null) {
return null;
}
int dimension = getArrayDimension(booleanArray);
return transferToIntArray(booleanArray, dimension);
}
}
这应该适用于任何数量的高达255的维度 - 我用5快速测试它似乎工作。 它也应该与'锯齿'数组一起使用,并使用null
s。
要使用它,请使用boolean
数组调用ArrayTransfer.transferToIntArray(...)
,它将返回相应的int
数组。 您当然需要将此方法的返回值强制转换为相关的int
数组类型。
这当然有改进的余地。 特别是,如果保留各种数组类的某些高速缓存,而不是仅仅为了获取它们的类而必须实例化空数组,那就更好了。
您可以对传递的参数的类型使用条件递归,并将convert1dToInt
用于维度1,然后在一个对象中收集结果,在给定的上下文中,您将被强制仅传递Object
类型的Object
并返回对象然后你投了它,这是一个小代码,提出了递归函数的想法,只是打印数组中元素的值:
public static void convertDimN(Object o) {
if (o.getClass().isArray() && Array.get(o, 0).getClass().isArray()) {
// is o a two dimentional array
for (int i = 0; i < Array.getLength(o); i++) {
convertDimN(Array.get(o, i));
}
} else
for (int i = 0; i < Array.getLength(o); i++) {
System.out.println(Array.get(o, i));
}
}
这将是你的第一个方法:
public static int[] convert1dToInt (boolean[] x) {
//int la = x.length; is useless since you are accessing an object member and not a method
int[] y = new int[x.length];
for (int a = 0; a < x.length; a++) {
y[a] = x[a] ? 1 :0;
}
return y;
}
只需重复使用您的代码 - 我没有太多时间,因为这是我的午休时间,所以我不知道是否一切正确,但方式应该适合:
public static int[][] convert2dToInt (boolean[][] x) {
int[][] y = new int[x.length][];
for (int a = 0; a < x.length; a++) {
y[a] = convert1dToInt (x[a]) ;
}
return y;
}
好吧,这个解决方案不是问题的答案,因为我没有准确地读出所询问的内容。 对不起。 据我所知,只要您使用原始数据类型,就不可能使用通用方法。 这是因为您不能将int []添加为int []的成员。 所以你应该使用Object [],Boolean []和Integer [],但我不知道你想如何使用它。 我不认为编写这样的方法是明智的,因为当你能够转换这样的数据结构时,你希望如何访问目标。 由于您不知道数组将具有多少维度,因此无法编写访问成员的通用方法。 我会尝试为此编写解决方案,因为我想知道我是否找到了其他可能的解决方案。 我是对的,问题是,如果可能而不是合理的话?
如果您告诉我们您想要使用此代码的用例,我想我们可以找到最佳解决方案。 正如我所说,当我有更多时间后,我会尝试寻找另一种解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.