함수형 인터페이스 ?

 

함수형 인터페이스란 1개의 추상 메소드를 갖는 인터페이스이다.여러개의 디폴트 메서드가 있더라도 추상 메소드가 1개라면 함수형 인터페이스가 된다.JAVA8 부터 인터페이스는 기본 구현체를 포함한 디폴트 메소드를 포함할 수 있으며,

자바의 람다 표현식은 함수형 인터페이스로만 사용 가능하다.

 

 

Functional Interface 생성

@FunctionalInterface
interface CustomInterface<T> {
    // abstract method 오직 하나
    T myCall();

    // default method 는 존재해도 상관없음
    default void printDefault() {
        System.out.println("Hello Default");
    }

    // static method 는 존재해도 상관없음
    static void printStatic() {
        System.out.println("Hello Static");
    }
}

위 인터페이스는 추상메소드를 1개 가지고 있기 때문에 함수형 인터페이스가 된다.

default method, static method 를 넣어도 문제가 되지 않는다.

@FunctionalInterface 를 선언하면 함수형인터페이스 형식에 맞지 않을 때 다음과 같은 에러를 띄운다.

 

Multiple non-overriding abstract methods found in interface com.practice.notepad.CustomFunctionalInterface

 

함수형 인터페이스를 이용한 람다식 표현

CustomInterface<String> customInterface = () -> "Hello Custom";

// abstract method
String s = customInterface.myCall();
System.out.println(s);

// default method
customInterface.printDefault();

// static method
CustomFunctionalInterface.printStatic();

String 타입을 래핑했기 때문에 myCall() 은 String 타입을 리턴한다.

그 외 default method, static method도 그대로 사용할 수 있다.

 

위 코드를 실행한 결과는 아래와 같다.

Hello Custom
Hello Default
Hello Static

 

JAVA8에서 기본적으로 제공하는 Functional Interface

 

함수형 인터페이스 Descripter Method
Predicate T -> boolean boolean test (T t)
Consumer T -> void void accept (T t)
Supplier () -> T T get()
Function<T, R> T -> R R apply(T t)
Comparator (T, T) -> int int compare (T o1, T o2)
Runnable () -> void void run()
Callable () -> T V call()

추가로 T와 R에 대해서 따로 찾아보았다.

T - 함수에 대한 입력 유형

R - 함수 결과의 유형

 

 

Predicate

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

Predicate는 인자 1개를 받아서 boolean 타입을 리턴한다.

람다식으로는 T -> boolean 으로 표현한다.

 

Consumer

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

Counsumer는 인자 1개를 받고 리턴이 없는 void 타입이다.

말그대로 소비하는 놈인 듯하다.

람다식으로는 T -> void 으로 표현한다.

 

Supplier

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Supplier는 아무런 인자값을 받지 않고 T타입의 객체를 리턴한다.

람다식으로는 () -> T 으로 표현한다.

위에 Consumer와 마찬가지로 이 친구 역시 공급자다운 이름값을 하는듯

 

Function<T, R>

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Function 은 T타입 인자를 받아서 R타입을 리턴한다.

람다식으로는 T -> R 으로 표현한다.

T와 R은 같은 타입을 사용할 수도 있다.

 

Comparator

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

Comparator은 2개의 T타입 인자를 받아서 int 타입을 리턴한다.

람다식으로는 (T, T) -> int 으로 표현한다.

 

Runnable

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Runable은 아무런 객체를 받지 않고 리턴도 하지 않는다.람다식으로 () -> void 으로 표현한다.

말그대로 실행만하는 친구인 듯하다.

 

Callable

@FunctionalInterface
public interface Callable<V> {
    V call() throws Exception;
}

Callable은 인자값을 받지 않고 T타입의 객체를 리턴한다.

람다식으로는 () -> T 으로 표현한다.

이 친구 역시 말그대로 어디선가 호출하면 튀어나가는 그런 모습인듯

Supplier 와 동일하게 인자값을 받지 않고 특정 타입을 리턴한다.

둘의 차이는 사실상 없다고 생각하면 된다.

 

단지 Callable 은 Runnable과 함께 병렬 처리를 위해 등장했던 개념으로서 ExecutorService.submit 같은 함수는 인자로 Callable 을 받는다.

 


람다식에 대한 내용은 위에 블로그한것 외에도 많은 것들이 있다.

Bi 인터페이스 라든지, 기본형 특화 인터페이스라든지 등등 상황에 따라서 검색하여 적절하게 사용하는 것도 능력이 될 수 있다고 생각한다.

 

 

 

 

'Backend > JAVA' 카테고리의 다른 글

[JAVA] Stream (스트림)  (0) 2022.06.20
[JAVA] Default method (디폴트 메소드)  (0) 2022.05.09
[JAVA] Lambda Expression(람다 표현식)  (0) 2022.01.27
[JAVA] JAVA 8 의 주요 변경사항  (0) 2022.01.27
[JAVA] lombok 롬복이란?  (0) 2022.01.22

+ Recent posts