繁体   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