Functional Interface의 종류

Updated: Categories:

Functional Interface의 종류를 알아보고 정리해보자

Functional Interface

  • 추상메소드가 하나만 존재하는 인터페이스
  • 인터페이스가 포함하는 메소드가 여러개여도 추상메소드만 하나면 조건 만족
  • Annotation (@FunctionalInterface) 를 달아주어 가독성을 좋게 만들자
  • 어떤 자세한 행위를 할지는 Host Code에서 람다표현식으로 오버라이딩하고 파라미터에 넣어준다.
@FunctionalInterface
interface MyInterface {
    // 메소드가 3개지만 추상메소드는 하나이므로 Functional Interface임
    void method1();
    default void method2() {};
    static void method3() {};
}
  • java에서 미리 정의한 Functional Interface는 크게 5가지로 나눌 수 있다.
  • Functional Interface의 모든 종류는 Oracle 공식 사이트에서 확인이 가능하다.


Runnable

  • Runnable은 인자를 받지 않고 리턴값도 없음
public interface Runnable {
    public abstract void run();
}


Supplier

  • 인자를 받지 않고 T 타입의 객체를 리턴
  • 데이터를 새로 생성할때 사용
public interface Supplier<T> {
    T get();
}


Consumer

  • T 타입의 객체를 인자로 받고 리턴 값은 없음
  • 인자를 두개 받을 수 있는 BiConsumer도 있다
  • 스트림에서 forEach 메소드 같은 Terminal Operation의 인자값으로 사용된다
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); };
    }
}


Function

  • T타입의 인자를 받고, R타입의 객체를 리턴
  • 스트림에서 map 같이 타입을 변환하는 메소드에 사용
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;
    }
}


Predicate

  • T타입 인자를 받고 결과로 boolean 값 리턴
  • 스트림에서 filter 메소드 등의 인자값으로 사용
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);
    }
}


총정리

  • java에서 제공하는 Functional Interface는 default method도 포함하고 있다는걸 알게됐다.
  • 근데 이번엔 Stream Lambda 식에서 메소드들의 인자값이 궁금해서 정리했기에 해당 내용은 뺐다.
  • 일단 각 종류가 어떤 역할을 하는지 아래표만 잘 알고 있으면 될 것 같다.
  인자값 리턴값 용도
Runnable X X 실행시키기
Supplier X T 데이터 생성
Consumer T X 데이터 사용
Function T R 타입 변환
Predicate T bool 조건식

참고

  • https://codechacha.com/ko/java8-functional-interface/
  • https://beomseok95.tistory.com/277