import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class DemoPercorsoLambda {
    @FunctionalInterface
    interface Operazione {
        int esegui(int a, int b);

        default String descrizione() {
            return "operazione su due interi";
        }
    }

    static int calcola(int a, int b, Operazione operazione) {
        return operazione.esegui(a, b);
    }

    static Operazione aggiungi(int incremento) {
        return (a, b) -> a + b + incremento;
    }

    static int somma(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        Operazione classeAnonima = new Operazione() {
            @Override
            public int esegui(int a, int b) {
                return a - b;
            }
        };
        Operazione lambda = (a, b) -> a - b;
        Operazione riferimento = DemoPercorsoLambda::somma;
        BinaryOperator<Integer> operatore = Integer::sum;
        Function<String, Integer> lunghezza = String::length;
        Predicate<String> lungo = testo -> lunghezza.apply(testo) >= 4;
        Supplier<String> etichetta = () -> "Java";

        System.out.println(calcola(10, 3, classeAnonima));
        System.out.println(calcola(10, 3, lambda));
        System.out.println(calcola(10, 3, riferimento));
        System.out.println(operatore.apply(10, 3));
        System.out.println(lungo.test(etichetta.get()));
        System.out.println(aggiungi(2).esegui(10, 3));
    }
}
