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
- auf bestimmtes Objekt anwenden
Class::method
reference::method