-
Functional InterfaceStudy/Effective Java 2023. 4. 17. 23:32
함수형 인터페이스
하나의 추상 메서드를 지정하는 인터페이스.
(default method 또는 static method 등을 포함하더라도 추상 메서드가 오직 하나면 함수형 인터페이스이다.)
lambda expression 또는 Method reference에 대한 target type을 제공한다.
public class UsageOfFunctions { public static void main(String[] args) { List<LocalDate> dates = new ArrayList<>(); dates.add(LocalDate.of(1982, 7, 15)); dates.add(LocalDate.of(2011, 3, 2)); dates.add(LocalDate.of(2013, 1, 28)); Predicate<LocalDate> localDatePredicate = d -> d.isBefore(LocalDate.of(2000, 1, 1)); Function<LocalDate, Integer> getYear = LocalDate::getYear; List<Integer> before2000 = dates.stream() .filter(localDatePredicate) .map(getYear) .collect(Collectors.toList()); } }
전체 표현식을 함수형 인터페이스의 인스턴스로 취급할 수 있다.
java에서 제공하는 기본 함수형 인터페이스 (
java.util.function
package) 를 익혀두자.https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Function<T, R>
T : the type of the input to the function.
R : the type of the result of the function.
@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; } }
Supplier<T>
T - the type of results supplied by this supplier.
@FunctionalInterface public interface Supplier<T> { T get(); }
Consumer<T>
T - the type of the input to the operation.
@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); }; } }
Predicate<T>
T - the type of the input to the predicate.
@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); } @SuppressWarnings("unchecked") static <T> Predicate<T> not(Predicate<? super T> target) { Objects.requireNonNull(target); return (Predicate<T>)target.negate(); } }
@FunctionalInterface
함수형 인터페이스임을 가리키는 annotation 이다.
선언되지 않아도 추상 메서드가 한 개라면 함수형 인터페이스로 사용할 수 있다.
@FunctionalInterface
로 인터페이스를 선언했지만 실제로 함수형 인터페이스가 아니라면 컴파일러가 에러(Multiple non-overriding abstract methods found in interface)를 발생시켜주므로, 선언해주는 것이 좋다.'Study > Effective Java' 카테고리의 다른 글
아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) 2023.04.25 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) 2023.04.23 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) 2023.04.16 객체 얼리기 (freezing) (0) 2023.04.12 빌더 패턴 (Builder pattern) - 롬복(Lombok) (0) 2023.04.11