lambdas

Lambda Expressions


Motivation

interface Predicate<T> {
    boolean test(T t);
}
Predicate<Integer> isEven = new Predicate<>() {
    @Override
    public boolean test(Integer i) {
        return i % 2 == 0;
    }
};

Redundante Information

  • new Predicate()
  • Signatur der Funktion (welche sonst)

Interessant: i % 2 == 0


Functional Interface

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);
    default Predicate<T> and(Predicate<? super T> other) { ... }
    static <T> Predicate<T> not(Predicate<? super T> target) { ... }
}
  • Single Abstract Method
  • beliebig viele implementierte
  • @FunctionalInterface

Lambda Expression

Voraussetzung: @FunctionalInterface

Predicate<Integer> isEven = new Predicate<>() {
    @Override
    public boolean test(Integer i) {
        return i % 2 == 0;
    }
};
Predicate<Integer> isEven = (i) -> {
    return i % 2 == 0;
};
isEven.test(42);

Generelle Syntax

Typ name = (params) -> { logic };

Kürzer!

Predicate<Integer> isEven = (i) -> {
    return i % 2 == 0;
};

return, { und } weglassen

Predicate<Integer> isEven = (i) -> i % 2 == 0;

bei nur einem Parameter: () weglassen

Predicate<Integer> isEven = i -> i % 2 == 0;
Comparator<String> byLength = (s1, s2) -> 
        Integer.compare(s1.length(), s2.length());

Methodenreferenzen

Predicate<Character> isDigit = c -> Character.isDigit(c);
Predicate<Character> isDigit = Character::isDigit;
Predicate<String> isEmpty = s -> s.isEmpty();
Predicate<String> isEmpty = String::isEmpty;
final String name = "not changing";
Predicate<String> isContainedInName = name::contains;
BiFunction<String, Integer, Character> charAt = String::charAt;
char c = charAt.apply("not recommended", 42);
  • statische Methoden / auf Argument anwenden
  • 
    Class::method
            
  • auf bestimmtes Objekt anwenden
  • 
    reference::method