首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中声明lambdas数组

在Java中声明lambdas数组
EN

Stack Overflow用户
提问于 2017-12-05 17:30:27
回答 4查看 6.1K关注 0票数 13

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

代码语言:javascript
复制
private interface I0 {
    int interface0(int a, int b);
}

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

现在,我如何声明一个同时包含I0和I1的列表呢?

代码语言:javascript
复制
List<Object> test = Arrays.asList(
        (int a, int b) -> a + b,
        (double d) -> d * 2
);

显然,Object不起作用。

EN

回答 4

Stack Overflow用户

发布于 2017-12-05 17:33:04

您必须首先将lambda表达式赋给函数接口类型的变量。

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

代码语言:javascript
复制
I0 i0 = (int a, int b) -> a + b;
I1 i1 = (double d) -> (int) (d * 2);
List<Object> test = Arrays.asList(
    i0,
    i1
);

也就是说,我不确定在List<Object>中存储这些lambda表达式的意义。如果不将它们转换回单独的函数接口类型,就不能使用它们。

票数 21
EN

Stack Overflow用户

发布于 2017-12-05 17:56:55

您可以强制转换为相应的接口,如下所示:

代码语言:javascript
复制
List<Object> test = Arrays.asList(
    (I0) (int a, int b) -> a + b,
    (I1) (double d) -> (int) (d * 2)
);

尽管这个更短,我也会考虑Eran's answer也许它更易读和更容易理解(如果有更多的函数)。而且我也看不到这样一个构造的用例...

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

代码语言:javascript
复制
List<Object> test = Arrays.asList(
    (I0) (a, b) -> a + b,
    (I1) d -> (int) (d * 2)
);
票数 14
EN

Stack Overflow用户

发布于 2017-12-06 02:47:36

据我所知,您正在尝试这样做:

代码语言:javascript
复制
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]
    }
}

然而,这个评论是一件非常重要的事情;你将如何实现它?

你可以在每一轮中检查类型:

代码语言:javascript
复制
    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而不使用循环:

代码语言:javascript
复制
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]));
}

对于动态解决方案,我建议切换到单个功能界面。我会使用最大要求,并在不需要的地方填充虚拟值:

代码语言:javascript
复制
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);
    }
}

或者,最好是您可以简化您的lambda:

代码语言:javascript
复制
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]));
    }
}

我觉得你的解决方案最终比这些解决方案都要简单。只是想帮你指明正确的方向。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47650162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档