2015-01-19 11 views
12

mi sono imbattuto il seguente codice Java che utilizza un riferimento metodo per System.out.printlnQual è l'espressione lambda equivalente per System.out :: println

class SomeClass{ 
    public static void main(String[] args) { 
      List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9); 
      numbers.forEach(System.out::println); 
     } 
    } 
} 

Qual è l'espressione lambda equivalente per System.out::println?

+3

Non è esattamente però funzionale :-) –

+0

@StephenC puoi suggerire perché? – Steve

+4

Beh, println' è difficilmente una funzione senza effetti collaterali ... lo è. –

risposta

22

Il metodo di riferimento System.out::println valuterà System.out prima, quindi creare l'equivalente di un'espressione lambda che cattura il valore valutato. Di solito, si usa
o->System.out.println(o) per ottenere lo stesso risultato del metodo, ma questa espressione lambda valuterà System.out ogni volta che verrà chiamato il metodo.

Quindi, un esatto equivalente sarebbe:

PrintStream p = Objects.requireNonNull(System.out); 
numbers.forEach(o -> p.println(o)); 

che farà la differenza se qualcuno invoca System.setOut(…); in-between.

+0

Capisco che l'obiettivo di invocazione di un riferimento al metodo sia valutato "quando viene rilevata per la prima volta la sua dichiarazione", che per me è logico. Ma c'è una parte jls che dice esplicitamente questo (ho davvero provato a trovarlo ...). Se il target di invocazione è un metodo, si può catturare il metodo e "questo" per esempio, non l'oggetto reale che il metodo restituisce ... per quanto ho capito. O ho sbagliato tutto questo? – Eugene

+0

non importa ... 'Innanzitutto, se l'espressione di riferimento del metodo inizia con un ExpressionName o un Primary, questa sottoespressione viene valutata' – Eugene

2

E ':

numbers.forEach(i -> {System.out.println(i);}); 

o ancora più semplice:

numbers.forEach(i -> System.out.println(i));