Espressione Lambda e riferimento al metodo [chiuso]


114

IntelliJ continua a propormi di sostituire le mie espressioni lambda con riferimenti a metodi.

C'è qualche differenza oggettiva tra entrambi?


4
Non proprio, non vedo nessun oggetto! A me sembra una chiamata statica
Gerard il

9
Ovviamente! Ma "non trovi neanche" ... È una questione di gusti, ero più preoccupato per gli aspetti più tecnici. In effetti, come hai già detto che sono la stessa cosa, questa è una buona risposta per me. Comunque, come lo propone IntelliJ, immagino che sia generalmente più apprezzato vedere un riferimento a un metodo piuttosto che un lambda (non per me, però).
Gerard

15
Il codice di un'espressione lambda viene compilato in un metodo sintetico mentre i riferimenti ai metodi funzionano senza (eccezione: costrutti speciali come Type[]::new). La classe anonima generata in fase di esecuzione sarà la stessa. Il JRE non fa alcuna differenza tra di loro. Quindi l'utilizzo di un riferimento al metodo ti farà risparmiare un metodo nel codice compilato, d'altra parte, non puoi fermarti a loro quando esegui il debug passo passo ...
Holger

6
Ora la domanda sta per essere chiusa ... Peccato per tutti gli utenti come me che non conoscono la differenza tra lambda e riferimenti, anche se non ce n'è una decisiva. Mi chiedo anche perché nessuno ha osato rispondere? Questa è la risposta giusta per me.
Gerard

3
Rispondere a una domanda chiusa di due anni è probabilmente una cattiva idea, ma per coloro che LEGGONO EFFETTIVAMENTE la domanda questo è ciò che il tutorial di Oracle ( docs.oracle.com/javase/tutorial/java/javaOO/… ) dice: I riferimenti ai metodi ... sono espressioni lambda compatte e di facile lettura per metodi che hanno già un nome.
domani

Risposte:


187

Consentitemi di offrire una prospettiva sul motivo per cui abbiamo aggiunto questa funzione al linguaggio, quando chiaramente non ne avevamo strettamente bisogno (tutti i ref dei metodi possono essere espressi come lambda.)

Nota che non esiste una risposta giusta . Chiunque dica "usa sempre un metodo ref invece di un lambda" o "usa sempre un lambda invece di un metodo ref" dovrebbe essere ignorato.

Questa domanda è molto simile nello spirito a "quando dovrei usare una classe con nome rispetto a una classe anonima"? E la risposta è la stessa: quando lo trovi più leggibile . Ci sono certamente casi che sono sicuramente uno o sicuramente l'altro ma c'è una miriade di grigi nel mezzo, e il giudizio deve essere usato.

La teoria dietro il metodo refs è semplice: i nomi contano . Se un metodo ha un nome, è spesso (ma non sempre!) Più chiaro e leggibile fare riferimento ad esso per nome, piuttosto che tramite un sacchetto di codice imperativo che alla fine si limita a girarsi intorno e lo invoca.

Gli argomenti sulle prestazioni o sul conteggio dei caratteri sono per lo più falsi errori e dovresti ignorarli. L'obiettivo è scrivere un codice che sia chiarissimo cosa fa. Molto spesso (ma non sempre!) Gli ref del metodo vincono con questa metrica, quindi li abbiamo inclusi come opzione, da utilizzare in quei casi.

Una considerazione chiave sul fatto che il metodo refs chiarisca o offusca l'intento è se è ovvio dal contesto qual è la forma della funzione rappresentata. In alcuni casi (ad esempio, è map(Person::getLastName)abbastanza chiaro dal contesto che è richiesta una funzione che mappa una cosa su un'altra, e in casi come questo, i riferimenti al metodo brillano. In altri, l'uso di un metodo ref richiede al lettore di chiedersi che tipo della funzione viene descritta; questo è un segnale di avvertimento che un lambda potrebbe essere più leggibile, anche se è più lungo.

Infine, quello che abbiamo scoperto è che la maggior parte delle persone all'inizio si allontana dai ref dei metodi perché si sentono ancora più nuovi e più strani dei lambda, e quindi inizialmente li trovano "meno leggibili", ma col tempo, quando si abituano alla sintassi, generalmente cambiano il loro comportamento e gravitano verso riferimenti al metodo quando possono. Quindi sii consapevole che la tua reazione soggettiva iniziale "meno leggibile" quasi certamente implica qualche aspetto di pregiudizio familiare, e dovresti darti la possibilità di metterti a tuo agio con entrambi prima di esprimere un'opinione stilistica.


25
@Gerard Grazie sarebbe stata una risposta migliore.
Yassin Hajaj

3
@Gerard Sembra che Brian stia dicendo "No, non c'è"
dj18

Brian, ottengo risultati diversi usando un riferimento al metodo e un lambda per lo stesso metodo. Non dovrebbero essere intercambiabili?
Michel Feinstein

@mFeinstein Per ogni ref del metodo, esiste un lambda equivalente (che potresti utilizzare o meno). Pubblica il codice come domanda?
Brian Goetz

Vorrei, ma temo che il codice possa essere troppo grande, poiché è un Android LiveData, all'interno di a Fragment, che ho convertito in un Eventche viene attivato da a ViewModel... e il comportamento diverso si verifica quando Android torna allo stesso Fragment.. .quindi faccio fatica a semplificarlo per una domanda
Michel Feinstein

10

Espressioni lambda lunghe costituite da diverse istruzioni possono ridurre la leggibilità del codice. In tal caso, estrarre tali istruzioni in un metodo e fare riferimento ad esso potrebbe essere una scelta migliore.

L'altro motivo potrebbe essere la riutilizzabilità . Invece di copiare e incollare la tua espressione lambda di poche istruzioni, puoi costruire un metodo e chiamarlo da punti diversi del tuo codice.


3
Confronta: houses.map(House::getName)e houses.map(h -> h.getName()). Il lambda richiede due caratteri in meno. È vero che il tipo non è esplicito, ma qualsiasi IDE te lo direbbe, e inoltre, i lambda dovrebbero essere usati quando il tipo è ovvio. Potrei essere d'accordo con te sulla riusabilità, ma i lambda sono precisamente piccoli, quindi possono essere concatenati invece di creare grandi metodi specifici. In questo senso, i metodi piccoli sono più riutilizzabili di alcuni metodi grandi e complessi e, a causa della chiarezza dei lambda (e in una certa misura, della verbosità) sono ancora facili da leggere.
Gerard

11
Sono con Gerald. La leggibilità in realtà soffre quando si sposta il codice, quindi è necessario saltarci sopra per continuare a leggere, quindi tornare indietro. Si vuole avere tutto il codice relativo allo stesso posto. Inoltre, Houseè un esempio molto favorevole; che dire ThreeStoryRedBrickHouseWithBlueDoors. Preferisco i riferimenti al metodo per lambda con più argomenti e talvolta per sottolineare che lambda riguarda solo una singola chiamata al metodo. C'è meno da sbagliare con un riferimento al metodo: potresti scrivere in modo errato l'argomento nel sito di utilizzo, facendo riferimento accidentalmente a una variabile dall'ambito esterno, ecc.
Marko Topolnik

@ Gerard Non sono d'accordo con la tua prima affermazione. Se si utilizzano nomi di metodi ben descrittivi e si estraggono grandi pile di codice, lo spostamento del codice migliora la leggibilità. Se usi nomi di metodi offuscanti, sono d'accordo con te.
Torsten
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.