Различия/оптимизация реализации между выражениями Lambda и анонимными классами

Предположим, что я хочу перебирать набор объектов.

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");

Как работает второй пример (без лямбда)? Новый объект (Predicate and Consumer) создается каждый раз, когда я вызываю код, насколько может java-компилятор java оптимизировать выражение лямбда? Для лучшего выполнения я должен объявить все 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

Как работает второй пример (без лямбда)? Новый объект (Predicate and Consumer) создается каждый раз, когда я вызываю код, насколько может java-компилятор java оптимизировать выражение лямбда? Для лучшего выполнения я должен объявить все lambdas как переменную и всегда передавать только ссылку?

Задача JIT - сделать так, чтобы вам не пришлось беспокоиться об этом. Например, JIT может (и, я полагаю, сделаю это) сделать так, чтобы s -> s.length == 10 автоматически становился статической константой, поэтому он повторно использовался во всем классе, а не только в этом экземпляре. Он может даже использоваться повторно в других классах, которые используют одну и ту же лямбду в другом месте.

Вся суть lambdas заключается в том, что вы должны просто написать простейший код, который имеет смысл, и JIT имеет свободу делать все, что нужно, чтобы сделать это эффективным. Например, почему lambdas сгенерированы с использованием invokedynamic вместо того, чтобы просто быть отстранены от анонимных внутренних классов.

Напишите простой код; доверяйте JIT, чтобы поступать правильно. Что это там для. Тем не менее, если вы хотите получить подавляющие, сложные подробные детали, это, это почти наверняка лучший источник.