Vedi questo sotto:
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Prova {
public static void main(String[] args) {
List<String> stringhe = Arrays.asList("arancia", "mela", "banana");
Predicate<String> predicato1 = str -> str.length() > 4;
Predicate<String> predicato2 = new Predicate<String>() {
public boolean test(String str) {
return str.length() > 4;
}
};
List<String> stringhe2 = stringhe.stream()
.filter(predicato1) // puoi passare predicato1 OPPURE predicato2
.collect(Collectors.toList());
System.out.println(stringhe);
System.out.println(stringhe2);
}
}
Qui ci sono DUE implementazioni della interfaccia funzionale Predicate<T> (parametrizzata String).
La prima implementazione è con una lambda expression.
La seconda implementazione è con una "anonymous" inner class (ma avrei potuto usare una nested class, una local class o una normalissima classe esterna a Prova .. NON importa).
Ed entrambe fanno nell'esempio la stessa cosa: "vero" se la stringa ha lunghezza maggiore di 4.
Quello che importa è che predicato1 e predicato2 fanno riferimento ad oggetti che IMPLEMENTANO la interfaccia Predicate.
Quindi al filter() dello stream posso passare indifferentemente predicato1 oppure predicato2
P.S. se hai dubbi sulle 43 interfacce funzionali in java.util.function, puoi vedere il mio "java.util.function Interfaces Cheat Sheet" che trovi
qui.