[英]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.