2015-08-01 6 views
26

Esiste una differenza nell'utilizzo dei seguenti componenti, a parte una leggibilità leggermente migliore in quest'ultimo?Creazione di istanze di nuovi oggetti durante l'utilizzo di stream Java 8

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

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

Sembra che intendiamo 'elemento -> new NewClass (elemento)', giusto? –

+0

Sì @TagirValeev spot on! – ShellDragon

+0

Downvoters, ti dispiacerebbe spiegare perché? – ShellDragon

risposta

32

Generalmente non c'è differenza. NewClass::new produce meno bytecode come nella versione lambda un metodo privato generato automaticamente viene creato dal compilatore java dal corpo lambda mentre NewClass:new collega direttamente all'handle del metodo del costruttore. Quindi usando i riferimenti al metodo potresti avere una dimensione del file di classe leggermente inferiore. Non ci sono tuttavia significative differenze nelle prestazioni.

Un'altra differenza è la procedura di risoluzione del metodo. Non è applicabile nel tuo esempio particolare, ma potrebbe essere applicabile in altri codici. Ad esempio, si hanno due costruttori:

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

E avere qualche metodo che accetta interfaccia funzionale:

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

Poi si può chiamare sia con lambda o interfaccia funzionale:

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

Ma supponiamo che in seguito aggiungerai un nuovo metodo con lo stesso nome:

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

Quindi la chiamata di riferimento al metodo diventerà ambigua e comporterà un errore di compilazione come NewClass::new ora corrisponde a entrambi i costruttori, mentre lambda è ancora univoco.

+0

Grazie per essere davvero completo. Apprezzo questo :) – ShellDragon

+0

Anche quando abbiamo il costruttore 'public NewClass (T data) {...}' e se usiamo 'map (NewClass :: new)' avremo un avviso _Type safety: The constructor NewClass (Object) appartiene al tipo raw NewClass. I riferimenti al tipo generico NewClass devono essere parametrizzati_ – Raghu