繁体   English   中英

在Java中声明lambdas数组

[英]Declare array of lambdas in Java

我想创建一个lambda数组。 问题是lambda可能彼此不同。 例:

private interface I0 {
    int interface0(int a, int b);
}

private interface I1 {
    int interface1(double d);
}

现在,我如何声明一个既可以包含I0又可以包含I1的列表?

List<Object> test = Arrays.asList(
        (int a, int b) -> a + b,
        (double d) -> d * 2
);

显然Object不起作用。

您必须首先将lambda表达式分配给功能接口类型的变量。

否则,编译器无法推断这些lambda表达式的类型。

I0 i0 = (int a, int b) -> a + b;
I1 i1 = (double d) -> (int) (d * 2);
List<Object> test = Arrays.asList(
    i0,
    i1
);

也就是说,我不确定将这些lambda表达式存储在List<Object> 如果不将它们转换回各个功能接口类型,则无法使用它们。

您可以转换到相应的界面,如:

List<Object> test = Arrays.asList(
    (I0) (int a, int b) -> a + b,
    (I1) (double d) -> (int) (d * 2)
);

尽管这个更短,但我也会考虑Eran的答案 ,它可能更容易理解(如果有更多功能)。 我也看不到这种结构的用例......

它变得更短(不一定更好):

List<Object> test = Arrays.asList(
    (I0) (a, b) -> a + b,
    (I1) d -> (int) (d * 2)
);

从我收集到的,你正试图做这样的事情:

public static void main(String... args){
    List<Object> lambdas = Arrays.asList(
            (IntBinaryOperator) (int a, int b) -> a + b,
            (DoubleToIntFunction) (double d) -> (int)(d * 2)
    );
    for(int i=0;i<args.length;i++){
        // Apply lambdas.get(i) to args[i]
    }
}

不过,这个评论非常重要; 你会如何实现它?

您可以在每轮检查中检查类型:

    for(int i=0;i<args.length;i++){
        if(lambdas.get(i) instanceof IntBinaryOperator){
            processedArgs[i] =
                    ((IntBinaryOperator) lambdas.get(i)).applyAsInt(MAGIC_NUMBER, Integer.parseInt(args[i]));
        }else{
            // All your other cases (may take a while)
        }
    }

验证每种可能的类型是一个巨大的痛苦,如果它是位置依赖的,它只会运行一次,所以它是过度的。

我的建议取决于它是静态的(你的代码只在一个特定的参数集上运行)还是动态的(它需要在所有类型的参数上运行)。 对于静态代码,我只是在没有循环的情况下应用lambdas:

public static void main(String... args){
    processedArgs = new int[args.length];
    IntBinaryOperator op1 = (int a, int b) -> a + b;
    DoubleToIntFunction op2 =  (double d) -> (int)(d * 2);

    processedArgs[0] = op1.applyAsInt(MAGIC_NUMBER, Integer.parseInt(args[0]));
    processedArgs[1] = op2.applyAsInt(Double.parseDouble(args[1]));
}

对于动态解决方案,我建议切换到单个功能接口。 我会满足最高要求并在不需要的地方填写虚拟值:

public static void main(String... args){
    processedArgs = new int[args.length];
    List<DoubleBinaryOperator> ops = Arrays.asList(
            (a, b) -> a + b,
            (d, ignore) -> (d * 2)
    );
    for(int i=0;i<args.length;i++){
        processedArgs[i] = (int)ops.get(i).applyAsDouble(Double.parseDouble(args[i]), MAGIC_NUMBER);
    }
}

或者,最好是,如果你可以简化你的lambdas:

public static void main(String... args){
    processedArgs = new int[args.length];
    List<DoubleToIntFunction> ops = Arrays.asList(
            (d) -> (int)(d + MAGIC_NUMBER),
            (d) -> (int)(d * 2)
    );
    for(int i=0;i<args.length;i++){
        processedArgs[i] = ops.get(i).applyAsInt(Double.parseDouble(args[i]));
    }
}

我觉得你的解决方案最终没有任何一个复杂。 只是想帮助指出你正确的方向。

你可以让你的界面使用vararg输入:

public class NaryFunctionTest {

    interface NaryFunction<R extends Number> {
        R run(R... args);
    }

    @Test
    public void test() {
        NaryFunction<Integer> f1 = (Integer[] o) -> o[0] + o[1];
        NaryFunction<Double> f2 = (Double[] o) -> o[0] *2;
        List<NaryFunction<?>> test = Arrays.asList(
            f1,
            f2
        );
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM