Un'espressione lambda è qualcosa di più di una classe interiore anonima con un singolo metodo?

39

C'è un nuovo hype con le espressioni lambda a lungo attese in Java 8; ogni 3 giorni un altro articolo appare con loro su quanto sono cool.

Per quanto ho capito, un'espressione lambda non è altro che una classe interna anonima con un singolo metodo (almeno a livello di byte-code). Oltre a ciò, viene fornito con un'altra simpatica caratteristica: inferenza di tipo, ma credo che l'equivalente di questo possa essere ottenuto con i generici su qualche livello (ovviamente non in modo così pulito come con espressioni lambda).

Sapendo questo, le espressioni lambda porteranno qualcosa di più di un semplice zuccheraggio sintattico in Java? Posso creare classi più potenti e flessibili o altri costrutti orientati agli oggetti con espressioni lambda che non è possibile creare con le funzionalità linguistiche correnti?

    
posta m3th0dman 16.04.2013 - 11:19
fonte

5 risposte

47

tl; dr: mentre è prevalentemente zucchero sintattico, quella sintassi più bella rende pratiche molte cose che erano utilizzate per terminare in infinite, illeggibili linee di parentesi graffe e parentesi.

Beh, in realtà è il contrario, perché i lambda sono molto più vecchi di Java. Le classi interne anonime con un singolo metodo sono (erano) le Java più vicine a lambda. È un'approssimazione che è stata "abbastanza buona" per qualche tempo, ma ha una sintassi molto spiacevole.

In superficie, i lambda di Java 8 sembrano non essere altro che zucchero sintattico, ma quando guardi sotto la superficie, vedi tonnellate di interessanti astrazioni. Ad esempio, la specifica JVM tratta un lambda in modo abbastanza diverso da un oggetto "vero" e, mentre è possibile gestirli come se fossero oggetti, la JVM non è tenuta a implementarli come tali.

Ma mentre tutti gli inganni tecnici sono interessanti e rilevanti (poiché consentono future ottimizzazioni nella JVM!), il vantaggio reale è "solo" la parte sintattica dello zucchero.

Che cosa è più facile da leggere:

myCollection.map(new Mapper<String,String>() {
  public String map(String input) {
    return new StringBuilder(input).reverse().toString();
  }
});

o

myCollection.map(element -> new StringBuilder(element).reverse().toString());

o (usando un metodo handle invece di un lambda):

myCollection.map(String::toUpperCase);

Il fatto che tu possa finalmente esprimere in modo sintetico che prima sarebbero state 5 linee di codice (di cui 3 sono assolutamente noiose) porta un vero cambiamento di ciò che è pratico (ma non di ciò che è è possibile, concesso).

    
risposta data 16.04.2013 - 11:35
fonte
14

Per Java, sì, non è altro che un modo migliore di creare una classe interiore anonima. Questo a causa della decisione fondamentale in Java che ogni bit di codice byte deve vivere all'interno di una classe specifica, che non può essere modificata ora dopo decenni di codice legacy da considerare.

Tuttavia, questo non è ciò di cui parlano veramente le espressioni lambda. Nei formalismi in cui sono concetti nativi piuttosto che una contorsione saltellante, i lambda sono elementi costitutivi fondamentali; sia la sintassi che l'atteggiamento delle persone nei loro confronti sono molto diversi. L'esempio di una funzione ricorsiva anonima creata esclusivamente da lambda in Struttura e interpretazione dei programmi per computer è in grado di cambiare l'intera concezione del calcolo. (Tuttavia, sono abbastanza certo che il modo di imparare a programmare è semplicemente esoterico per diventare una storia di successo mainstream.)

    
risposta data 16.04.2013 - 12:22
fonte
2

Sì, è solo uno zucchero sintattico, nel senso che ovunque scrivi un lambda, puoi riscrivere quell'espressione come un'espressione anonima della classe interna con un metodo, in cui la classe implementa l'interfaccia funzionale dedotta per il lambda contesto, e sarebbe esattamente equivalente semanticamente. E puoi farlo sostituendo semplicemente l'espressione lambda con l'espressione della classe anonima, senza modificare alcuna altra espressione o linea di codice.

    
risposta data 16.04.2013 - 23:37
fonte
0

Joachim Sauer ha già fatto un buon lavoro rispondendo alla domanda, ma ha solo accennato a qualcosa che considero importante. Dal momento che Lambdas non sono classi, non sono nemmeno compilati come tali. Tutte le classi interne anonime portano alla creazione di un file .class che a sua volta deve essere caricato da ClassLoader. Quindi usare Lambdas non solo rende il tuo codice più bello, ma riduce anche le dimensioni del tuo codice compilato, l'impronta di memoria del tuo ClassLoader e il tempo necessario per trasferire i bit dal tuo disco rigido.

    
risposta data 23.06.2016 - 17:12
fonte
-1

No. Non lo sono.

Un altro modo per dirla è che i lambda sono un modo non orientato agli oggetti, per quanto conciso, per ottenere la stessa cosa che una classe anonima o, la mia preferenza, la classe interiore otterrebbero in un modo orientato agli oggetti.

    
risposta data 19.02.2014 - 19:10
fonte

Leggi altre domande sui tag