2015-08-01 6 views
26

Есть ли разница в использовании следующих комбинаций, отличных от немного лучшей читаемости в последнем?Создание нового объекта при использовании потоков Java 8

someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList()); 

someList.stream().map(NewClass::new).collect(Collectors.toList()); 
+3

Кажется, что вы имеете в виду 'item -> новый NewClass (item)', правильно? –

+0

Да @TagirValeev пятно на! – ShellDragon

+0

Downvoters, не могли бы вы объяснить, почему? – ShellDragon

ответ

32

Вообще-то нет разницы. NewClass::new производит меньше байт-кода, как в лямбда-версии, автоматически созданный частный метод создается java-компилятором из тела лямбда, тогда как NewClass:new напрямую ссылается на дескриптор метода конструктора. Таким образом, используя ссылки на методы, вы можете иметь немного меньше размера файла класса. Однако существенной разницы в производительности не ожидается.

Еще одно отличие - процедура разрешения метода. Он не применим в вашем конкретном примере, но может применяться в другом коде. Например, у вас есть два конструктора:

public NewClass(String a) {...} 
public NewClass(String a, String b) {...} 

А у вас есть какой-то метод, который принимает функциональный интерфейс:

public myMethod(Function<String, NewClass> fn) {...} 

Тогда вы можете назвать его как с лямбда или функционального интерфейса:

myMethod(str -> new NewClass(str)); 
myMethod(NewClass::new); 

Но предположим, что позже вы добавляете новый метод с тем же именем:

public myMethod(BiFunction<String, String, NewClass> fn) {...} 

Затем вызов метода будет неоднозначным и приведет к ошибке компиляции, так как NewClass::new теперь соответствует обоим конструкторам, в то время как лямбда по-прежнему недвусмысленна.

+0

Спасибо за то, что он действительно всеобъемлющий. Цените это :) – ShellDragon

+0

Также, когда у нас есть конструктор 'public NewClass (T data) {...}', и если мы будем использовать 'map (NewClass :: new)', мы получим предупреждение _Type safety: Конструктор NewClass (Object) относится к исходному типу NewClass. Ссылки на общий тип NewClass следует параметризовать_ – Raghu

 Смежные вопросы

  • Нет связанных вопросов^_^