在java 8中使用lambda表达式有什么好处?

时间:2015-11-03 05:47:24

标签: java lambda java-8

Interface AccountService{
    public void createAccount();
}

AccountService accountServiceAnonymous = new AccountService(){
    public void createAccount(){
        Account account = new Account();
        save(account);
    }
};

AccountService accountServiceLambda = () -> {
    Account account = new Account();
    save(account);
}

除了减少代码行数之外,在java 8中使用lambda表达式还有其他优点吗?

6 个答案:

答案 0 :(得分:18)

添加@Bilbo在评论中提到的内容。在Java 1.7中,发布了一个名为invokedynamic的新JVM Opcode,Java 8 Lambda使用了它。因此,以下代码将导致在编译代码时创建Anonymous类。可能<ClassName>$1.class所以如果你有10个匿名类,那么在最后一个jar中还有10个类。

AccountService accountServiceAnonymous = new AccountService(){
    public void createAccount(){
        Account account = new Account();
        save(account);
    }
};

但Java 8 lambda使用invokedynamic来调用lambdas,因此如果你有10个lambdas,它将不会导致任何匿名类,从而减少最终的jar大小。

AccountService accountServiceLambda = () -> {
    Account account = new Account();
    save(account);
}

答案 1 :(得分:6)

将lambdas(和方法引用)与Stream API和Java 8中添加的其他功能(例如Java 8)相结合时,可以看到它们的另一个优点。可选的。

考虑以下代码:

private void pushToFront(AbstractInfo contactInfo) {
        registeredWindows.stream()
            .filter(window -> window.getWindowId() == contactInfo.getId())
            .findAny()
            .ifPresent(Window::pushToFront);
    }

该方法过滤与windowId匹配的已注册窗口列表,其中联系人的id返回Optional。如果列表包含具有匹配id的窗口,则可以使用Optional中的值,然后使用pushToFront方法。将其与相同的功能相比较,但用Java 7编写:

private void pushToFront(AbstractInfo contactInfo) {
    for (Window window : registeredWindows) {
        if (window.getWindowId() == contactInfo.getId() {
            window.pushToFront();
        }
    }
}

至少对我来说,带有lambda表达式,流和方法引用的代码更简洁和可读(当你习惯使用流时)。上面的例子非常简单 - 但考虑一个,在Java 7中需要嵌套循环,多个条件语句等。不容易阅读甚至更难以忽略正在发生的事情。

Lambda然后允许人们充分利用Java 8的其他整洁功能,其中包括整洁,干净,高效且易于理解的代码。

最重要的是,您应该将lambda表达式视为更大整体的一部分,这些表达式本身很好,但与Java 8的其他“构建块”结合使用时更好。

答案 2 :(得分:4)

还有一个 - 与匿名类不同,lambdas不创建新范围,它们与封闭块/环境共享相同的范围。

所以:

  1. 访问封闭对象更容易 - 普通EnclosingClass.this引用是指封闭类的实例(您不需要说Observable<Response> track(@Body RequestBody body);

  2. 没有shadowing问题(因为您无法定义与封闭范围中的变量同名的局部变量)

答案 3 :(得分:2)

lambda表达式的优点

  1. 减少了代码行。
  2. 它通过在方法中传递行为来支持顺序和并行执行 使用收集流API。
  3. 使用Stream API和lambda表达式,我们可以在集合上进行批量操作时实现更高的效率(并行执行)。

答案 4 :(得分:1)

Lambdas提供的(更多)优势是懒惰(从而提高了性能):


在Lambda之前 ,一条日志语句如下所示:

?

无论是否启用跟踪,class Sample { public static void setFieldsMap(int fieldTag, Function< Integer, ? > messageGetter, String fieldKey ) { messageGetter.apply(fieldTag); } } 都会被调用,这会浪费CPU周期。

为了避免此类昂贵的调用,我们曾经写过:

logger.trace("Costly Metrics: {}", expensiveCompuatation());

尽管它满足了需求,但是现在代码看起来很丑陋,带有更多的expensiveCompuatation()语句,导致代码膨胀。


在Lambdas 之后,现在log语句看起来简洁明了(没有if语句的周围),并允许延迟昂贵的操作:

if (logger.isTraceEnabled()) {
    logger.trace("Costly Metrics: {}", expensiveCompuatation());
}

答案 5 :(得分:0)

除了这里所说的内容,并严格回答所提出的问题,重要的是将lambdas视为代码块&#34;除其他外,它可以作为参数传递。由于您可以删除重复代码,因此这提供了巨大的优势。

那是怎么回事?在上面由@Kitke提供的示例中, pushToFront (...)方法,如果需求存在,可能会稍微重构为模板,并用于通过任何条件过滤registeredWindows 即可。 lambda表达式窗口 - &gt; window.getWindowId()== contactInfo.getId(),在这种情况下可以作为参数传递。如果没有这个强大的功能,每次需要按不同条件过滤 registeredWindows 集合时,都必须编写 while 循环。巨大的收获,重新考虑你的代码。

摘自:http://www.copypasteisforword.com/notes/lambda-expressions-in-java。在那里你可以找到另一个lambda用法的例子来删除重复的代码。