如何在Java中定义和调用内联lambda表达式

时间:2016-10-24 10:41:34

标签: lambda java-8

我想做这样的事情:

{ param -> if ( <condition over param> ) process ( param ) } ( provider () );

即,param是一个方法返回的值(比如说,需要很长时间才能运行,所以我只想调用一次)并且我只想在满足条件的情况下传递这样的值。

替代方案是:

Param param = provider(); if ( <cond> ) process ( param );

但基于lambda的版本,如果我可以使其工作,将会更短。上面的代码不能用Java编译,我无法弄清楚我在想什么是可能的以及如何。

4 个答案:

答案 0 :(得分:4)

嗯,你可以做点什么

                                        // use Type::process for a static method
Stream.of(provider()).filter( «cond» ).forEach(this::process);

虽然这里的普通命令陈述确实没有任何好处

如果要限制新引入的变量的范围,可以创建一个块。

{ Param param = provider(); if( «cond» ) process(param); }

并且,作为旁注,使用这种传统结构可以更容易地进行调试。

答案 1 :(得分:1)

感谢大家的回复。我发现了一种类似于@Holger建议的方法:

Optional.of ( provider() ).map ( v -> { if ( <cond> ) process ( v ); return null; } )

(仅当process()返回void时才返回)。我同意它更快地定义一个中间变量,我可能最终会这样做。然而,必须有一些心理上的原因,为什么我会更多地吸引上述功能形式。当他们很多时,他们似乎写得更快,也许是因为你不需要考虑新的变量名(如果涉及不同类型,你需要多个变量定义)。

答案 2 :(得分:1)

以下完整示例程序的语法与您所说的相当接近。这取决于可用于其他类似场景的通用“调用”功能。 lambda的主体需要括号,因为它是一个陈述,而不是表达。该示例具有String param类型,但它可以是任何类型。

import java.util.function.Consumer;

public class invoke_lambda_directly
{
    void run()
    {
        invoke(param -> { if (param.equals("x")) process(param); }, provider() );
    }

    private void process(String p) { System.out.println("processed " + p); }

    private String provider() { return "x"; }

    public static <T> void invoke(Consumer<T> i, T t) { i.accept(t); }

    public static void main(String args[])
    {
        new invoke_lambda_directly().run();
    }
}

答案 3 :(得分:0)

在不知道您的具体情况的情况下,我同意JB Nizet的评论,认为替代解决方案是可取的。除此之外,要将其写为lambda表达式,您只需要更改一些标点符号。此外,lambda表达式实现的功能接口必须是已知的,例如java.util.function.Consumer

    Consumer<Param> consumer = param -> { if ( !"".equals ( param ) ) process ( param ); };
    consumer.accept(provider());