본문 바로가기
Language/Java

[Java] Functional Interface

by 1000zoo 2023. 10. 24.

Functional Interface란?

Functional Interface는 Java에서 함수형 프로그래밍을 가능하게 하는 인터페이스다. 이 인터페이스는 오직 하나의 추상 메서드를 가지고 있어야 하며, 람다 표현식이나 메서드 참조를 사용해서 간단하게 인스턴스를 생성할 수 있다. Java 8에서 도입된 이 기능은 코드를 더 간결하고 이해하기 쉽게 만들어준다.

Java에서 제공하는 Functional Interfaces

Runnable

Descriptor: () -> void
Method: void run()

ex

Runnable runnable = () -> {
    System.out.println("running");
}
//사용
runnable.run();

Consumer<T>

Descriptor: (T) -> void
Method: void accept(T t)

ex

Consumer<String> printString = (str) -> System.out.println(str);  
// 사용
printString.accept("Hello, world!");

Supplier<T>

Descriptor: () -> T
Method: T get()

ex

Supplier<Date> getCurrentDate = () -> new Date();  
// 사용 
Date date = getCurrentDate.get();

Predicate<T>

Descriptor: (T) -> boolean
Method: boolean test(T t)

ex

Predicate<Integer> isPrime = (o) -> {
    for (int i = 2; i <= (int) Math.sqrt(o); i++) {
        if (o % i == 0) {
           return false;
        }
    }
    return true;
};  
// 사용
boolean result = isPrime.test(5);

Function<T, R>

Descriptor: (T) -> R
Method: R apply(T t)

ex

Function<Integer, String> convertToString = (num) -> String.valueOf(num);  // 사용
String result = convertToString.apply(123);

UnaryOperator<T>

Descriptor: (T) -> T
Method: T apply(T t)

ex

UnaryOperator<Integer> square = (num) -> num * num;  
// 사용
int result = square.apply(4);

BinaryOperator<T>

Descriptor: (T, T) -> T
Method: T apply(T t1, T t2)

ex

BinaryOperator<Integer> sum = (num1, num2) -> num1 + num2;  
// 사용 int
result = sum.apply(3, 4);

이 외에도 BiFunction<T, U, R>, BiPredicate<T, U>, BiConsumer<T, U> 등과 같은 여러 Functional Interfaces가 있다. 이들 인터페이스는 각각 두 개의 매개변수를 받아서 처리하고, 해당 연산을 수행한다.

기본형 인터페이스

위에서 본 제네릭 인터페이스를 제외하고, 기본형에서 사용할 수 있는 인터페이스들도 제공한다.
주로 기존의 인터페이스명에서 Int, Long, Double 이 붙게된다. Function<T, R>의 경우, TToRFunction과 같이 표기된다. (ex, Function<Integer, Double> => IntToDoubleFunction) Function의 경우에는 제네릭과 병행하여 다음과 같이 사용할 수도 있다.

IntFunction<R>: integer를 받아 R 리턴
ToIntFunction<T> T를 받아 integer 리턴

Custom Functional Interface

만약, 더 많은 매개변수가 필요하거나, 다른 종류의 함수 인터페이스가 필요하다면, 아래의 예시와 같이 만들 수 있다.

ex

// MultipleParameters.java
@FunctionalInterface
public interface MultipleParameters<A, B, C, D> {
    D doSomething(A a, B b, C c);
}

// MultipleParametersTest.java  
static final MultipleParameters<Integer, Integer, Integer, Integer> testFunction = (o1, o2, o3) -> o1 + o2 + o3;

//사용
testFunction.doSomething(1, 2, 3);

참고

https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
https://bcp0109.tistory.com/313
https://developer-talk.tistory.com/460