簡體   English   中英

任意維數組作為方法參數

[英]Array of arbitrary dimension as method parameter

我有一個簡單的轉換方法,用於從booleanint的數組:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM