Sobes.tech
Middle

Cosa sono le espressioni lambda in Java e quali funzionalità offrono?

sobes.tech AI

Risposta dell'AI

Le espressioni lambda in Java sono una sintassi concisa per creare funzioni anonime (metodi senza nome) che possono essere passate come argomenti o memorizzate in variabili. Fondamentalmente, sono interfacce funzionali implementate "al volo".

Le principali funzionalità offerte dalle espressioni lambda:

  • Semplificazione della sintassi: Riducendo significativamente il codice boilerplate quando si lavora con interfacce funzionali rispetto alle classi interne anonime.

    // Prima delle lambda:
    Runnable classicRunnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("Runnable classico");
        }
    };
    
    // Con lambda:
    Runnable lambdaRunnable = () -> System.out.println("Runnable lambda");
    
  • Programmazione funzionale: Permettono di scrivere codice più funzionale, dove le funzioni sono cittadini di prima classe e possono essere passate come dati. Questo è fondamentale per lavorare con l'API Stream.

    // Filtraggio di una lista usando lambda
    List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
    List<String> filteredNames = names.stream()
                                     .filter(name -> name.startsWith("A"))
                                     .collect(Collectors.toList());
    
  • Lavoro con l'API Stream: Le espressioni lambda sono la base per la maggior parte delle operazioni in Stream API (filter, map, forEach, reduce, ecc.), garantendo concisione ed esecuzione parallela.

    // Trasformazione e output degli elementi dello stream
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    numbers.stream()
           .map(n -> n * n) // lambda per il mapping
           .forEach(System.out::println); // riferimento al metodo (alternativa alla lambda)
    
  • Miglioramento della leggibilità: Per operazioni semplici, le lambda rendono il codice più leggibile e comprensibile, concentrandosi sull'operazione stessa e non sulla sintassi della classe anonima.

  • Implementazione di interfacce funzionali: Possono essere usate ovunque ci si aspetti un'istanza di un'interfaccia funzionale (interfaccia con un metodo astratto singolo).

Sintassi dell'espressione lambda: (parametri) -> { corpo }

Esempi:

  • Senza parametri, senza valore di ritorno: () -> System.out.println("Ciao")
  • Con un parametro, senza valore di ritorno: name -> System.out.println("Ciao, " + name) (si può omettere le parentesi attorno a un singolo parametro)
  • Con più parametri, senza valore di ritorno: (x, y) -> System.out.println(x + y)
  • Con parametri, con valore di ritorno: (a, b) -> a + b (se il corpo è un'espressione singola, il suo valore viene restituito implicitamente)
  • Con parametri, con blocco di codice e valore di ritorno: (a, b) -> { int sum = a + b; return sum; } (è necessario return esplicito per i blocchi di codice)