Interfacce Funzionali Predefinite in Java
- Le interfacce funzionali predefinite in Java forniscono un insieme di interfacce comuni che possono essere utilizzate con le espressioni lambda.
- Queste interfacce semplificano la scrittura di codice funzionale e migliorano la leggibilità del codice.
- Le interfacce funzionali predefinite coprono una vasta gamma di operazioni comuni, come operazioni su numeri, stringhe e collezioni.
- Utilizzare le interfacce funzionali predefinite può ridurre la necessità di definire interfacce funzionali personalizzate, rendendo il codice più conciso e manutenibile.
Interfacce Funzionali Predefinite
Fino a questo punto, gli esempi nelle lezioni precedenti hanno definito le proprie interfacce funzionali in modo che i concetti fondamentali dietro le espressioni lambda e le interfacce funzionali potessero essere illustrati chiaramente.
Tuttavia, in molti casi, non sarà necessario definire le proprie interfacce funzionali perché il pacchetto chiamato java.util.function
ne fornisce diverse predefinite.
Anche se le esamineremo più da vicino nelle future lezioni, ecco un elenco delle interfacce funzionali predefinite più comunemente utilizzate:
Interfaccia | Scopo |
---|---|
UnaryOperator<T> |
Applica un'operazione unaria a un oggetto di tipo T e restituisce il risultato, che è anche di tipo T . Il suo metodo si chiama apply() . |
BinaryOperator<T> |
Applica un'operazione a due oggetti di tipo T e restituisce il risultato, che è anche di tipo T . Il suo metodo si chiama apply() . |
Consumer<T> |
Applica un'operazione su un oggetto di tipo T . Il suo metodo si chiama accept() . |
Supplier<T> |
Restituisce un oggetto di tipo T . Il suo metodo si chiama get() . |
Function<T, R> |
Applica un'operazione a un oggetto di tipo T e restituisce il risultato come un oggetto di tipo R . Il suo metodo si chiama apply() . |
Predicate<T> |
Determina se un oggetto di tipo T soddisfa qualche vincolo. Restituisce un valore boolean che indica il risultato. Il suo metodo si chiama test() . |
Il seguente programma mostra l'interfaccia Function
in azione utilizzandola per rielaborare l'esempio visto in precedenza chiamato DemoLambdaBlocco
che dimostrava i lambda a blocco implementando un esempio fattoriale. L'esempio è riportato qui per comodità:
// Una lambda a blocco che calcola il fattoriale di un valore int.
// Un'interfaccia funzionale che dichiara il metodo funzione().
interface FunzioneNumerica {
int funzione(int n);
}
class DemoLambdaBlocco {
public static void main(String[] args)
{
// Questa lambda a blocco calcola il fattoriale di un valore int.
FunzioneNumerica fattoriale = (n) -> {
int risultato = 1;
for(int i=1; i <= n; i++)
risultato = i * risultato;
return risultato;
};
// Usiamo la lambda a blocco per calcolare il fattoriale di 3 e 5.
System.out.println("Il fattoriale di 3 è " + fattoriale.funzione(3));
System.out.println("Il fattoriale di 5 è " + fattoriale.funzione(5));
}
}
Quest'esempio creava la propria interfaccia funzionale chiamata FunzioneNumerica
, ma avrebbe potuto utilizzare l'interfaccia Function
incorporata, come illustra questa versione del programma:
// Utilizza l'interfaccia funzionale incorporata Function.
// Importa l'interfaccia Function.
import java.util.function.Function;
class UsaInterfacciaFunctionDemo {
public static void main(String[] args) {
// Questa lambda a blocco calcola il fattoriale di un valore int.
// Questa volta, Function è l'interfaccia funzionale.
Function<Integer, Integer> fattoriale = (n) -> {
int risultato = 1;
for (int i = 1; i <= n; i++)
risultato = i * risultato;
return risultato;
};
// Stampa il fattoriale di 3 e 5.
// Utilizza il metodo apply dell'interfaccia Function.
System.out.println("Il fattoriale di 3 è " + fattoriale.apply(3));
System.out.println("Il fattoriale di 5 è " + fattoriale.apply(5));
}
}
L'output di questo programma è lo stesso del programma precedente:
Il fattoriale di 3 è 6
Il fattoriale di 5 è 120