如何在Java中明智地将函数应用于数组元素?

时间:2019-01-15 20:43:20

标签: java arrays

假设我有3个功能,例如y_1(x) = x^2y_2(x) = x+1y_3(x) = x/5。 如何将这些函数以元素明智的方式应用于任何多维浮点数组?

现在假设我拥有函数y_1y_2y_3,那么将任意函数应用于任何大小和形状的float数组的函数是什么?

我尝试创建一个接受任何函数的函数应用程序,然后将其应用于二维情况下双循环中的每个元素,但是我什至无法使函数应用程序接受另一个函数作为输入。

我尝试执行以下操作

public float[][] elemen_wise_function(  float[][] x,
                                        int Size_axis_0,
                                        int Size_axis_1,
                                        Callable<> myFunc) {

    float[][] Constructed_array = new float[Size_axis_0][Size_axis_1];
    for (int i=0; i<Size_axis_0; i++) {
        for (int j = 0; j < Size_axis_1; j++) {
            Constructed_array[i][j] = (float) myFunc(x[i][j]) ;
        }
    }
    return Constructed_array;
}

但这失败了,因为我找不到将myFunc传递给elemen_wise_function的方法。

3 个答案:

答案 0 :(得分:2)

一种解决方案是将myFunc声明为UnaryOperator<Float>

public float[][] elemen_wise_function(float[][] x, int Size_axis_0, int Size_axis_1,
                                      UnaryOperator<Float> myFunc) {

不幸的是,这会自动float来回装箱。

如果您需要提高性能,则可以定义一个自定义接口,该接口经过硬编码后可以在原始float上运行:

interface FloatOperator {
    float apply(float x);
}

public float[][] elemen_wise_function(float[][] x, int Size_axis_0, int Size_axis_1,
                                      FloatOperator myFunc) {

在两种情况下都用作:

    for (int i = 0; i < Size_axis_0; i++) {
        for (int j = 0; j < Size_axis_1; j++) {
            Constructed_array[i][j] = myFunc.apply(x[i][j]);
        }
    }

作为示例调用:

    elemen_wise_function(array, size0, size1, a -> 1/a);

答案 1 :(得分:0)

非常酷,您可以传递lambda(从Java 8开始):

public float[][] elemen_wise_function(float[][] x,
                                      Function<Float, Float> f) {

    float[][] Constructed_array = new float[x.length][x[0].length];
    for (int i=0; i<x.length; i++) {
        for (int j = 0; j < x[0].length; j++) {
            Constructed_array[i][j] = f.apply(x[i][j]);
        }
    }
    return Constructed_array;
}

然后,您可以传递定义为lambda的任何函数,例如:

Function<Float, Float> fun = x -> 2 * x;

还有一个注意事项-在Java中使用camelCase作为方法名称;)

答案 2 :(得分:0)

如果您尝试使用Java 6进行此操作,则可以执行类似的操作。

    import java.util.Arrays;
    import java.util.function.Function;

    public interface MapFunction {
        public float map(float value);
    }

    public static float[][] map2DArray(float[][] floatArrays, MapFunction mapper) {
        final float[][] retval = new float[floatArrays.length][];
        for (int i = 0; i < floatArrays.length; i++) {
            float [] floats = floatArrays[i];
            retval[i] = new float[floats.length];
            for (int j = 0; j < floats.length; j++) {
                retval[i][j] = mapper.map(floats[j]);
            }
        }
        return retval;
    }

或者在Java 8中,您不介意使用Float

    import java.util.Arrays;
    import java.util.function.Function;

    public static Float[][] map2DArray(Float[][] floatArrays, Function<Float, Float> mapper) {
        return Arrays.stream(floatArrays).map((Float[] floats) -> 
                Arrays.stream(floats).map(mapper).toArray(Float[]::new)
        ).toArray(Float[][]::new);
    }