람다식(Lambda Expression)은 메소드를 직접 정의하지 않고, 하나의 '식'으로 표현한 것이다.
람다식은 불필요한 코드를 줄이고, 가독성을 높이기 위해 사용!
// method block
public int sum(int a, int b) {
return a + b;
}
// lambda
(int a, int b) -> {
return a + b;
}
(int a, int b) -> { return a + b; }
(int a, int b) -> a + b;
(a, b) -> a + b;
오직 하나의 method 선언을 갖는 interface로 함수를 일급객체처럼 다룰 수 있게 도와주는 것이다.
람다식은 FunctionalInterface 기반으로만 작성이 가능하다.
@FunctionalInterface
interface Calculate {
int sum(int a, int b);
// default int plus(int a, int b) { return a + b; }
// static int sub(int a, int b) { return a - b; }
}
매개변수 없이 반환 값만을 가지는 인터페이스
@FunctionalInterface
public interface Supplier<T> {
T get();
}
T 매개변수를 받으며, 반환 값은 없다.
andThen
을 사용하여 Consumer를 연쇄적으로 사용할 수 있다.
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() { return t -> t; } }
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object);
}
}