Lambda表达式和匿名类之间的实现差异/优化

时间:2015-09-02 18:29:12

标签: java lambda java-8 java-stream

让我们假设我想迭代一组对象。

List<String> strmap = ...
//Without lambdas
strmap.stream().filter(new Predicate<String>() {
      public boolean test(String string) {
          return string.length == 10;
      }
}.forEach(new Consumer<String>() {
      public void accept (String string) {
          System.out.println("string " + string + " contains exactly 10 characters");
      }
} 
//With lambdas
strmap.stream()
      .filter(s -> s.length == 10)
      .forEach(s -> System.out.println("string " + s + " contains exactly 10 characters");

第二个例子(没有lambdas)如何工作?每次调用代码时都会创建一个新对象(Predicate和Consumer),java jit编译器可以优化lambda表达式多少?为了获得更好的性能,我应该将所有lambdas声明为变量并始终仅传递引用吗?

private Predicate<String> length10 = s -> s.length == 10;
private Consumer<String> printer = s -> { "string " + s + " contains exactly 10 characters"; }

strmap.stream()
      .filter(length10)
      .forEach(printer);

1 个答案:

答案 0 :(得分:6)

  

第二个例子(没有lambdas)如何工作?每次调用代码时都会创建一个新对象(Predicate和Consumer),java jit编译器可以优化lambda表达式多少?为了获得更好的性能,我应该将所有lambdas声明为变量并始终仅传递引用吗?

JIT的工作就是让你不必担心这一点。例如,JIT可以(并且,我相信,将)使s -> s.length == 10自动变为静态常量,因此它在整个类中重复使用,而不仅仅是该实例。它甚至可以在其他使用相同lambda的类中重用。

lambdas的全部意义在于你应该编写最简单的代码,而JIT可以自由地做任何需要的事情来提高效率。例如,这就是为什么lambda是使用invokedynamic生成的,而不是简单地将它们放到匿名内部类中。

编写直截了当的代码;相信JIT做正确的事。这就是它的用途。这就是说,如果你想要压倒性的,复杂的细节,this几乎肯定是最好的来源。