들어가며
자바에서는 다양한 함수형 인터페이스들을 제공한다. 다음 표가 그 예이다.
인터페이스 | 함수 시그니처 | 예 |
---|---|---|
UnaryOperator |
T apply(T t) | String::toLowerCase |
BinaryOperator |
T apply(T t1, T t2) | BigInteger::add |
Predicate |
boolean test(T t) | Collection::isEmpty |
Function |
R apply(T t) | Arrays::asList |
Supplier |
T get() | Instant::now |
Consumer |
void accept(T t) | System.out::println |
표준 함수형 인터페이스 대부분은 기본 타입만 지원한다. 그렇다고 기본 함수형 인터페이스에 박싱된 기본 타입을 넣어 사용하지는 말자. 표준 함수형 인터페이스는 대부분의 상황을 제공한다. 그럼 함수형 인터페이스를 작성해야 하는 때는 언제일까?
- 자주 쓰이며 이름 자체가 용도를 명확히 설명해준다. 예를 들어 Comparator
와 ToIntBiFunction 가 있다. Comparator 가 ToIntBiFunction 보다 명확하다. - 반드시 따라야 하는 규약이 있다.
- 유용한 디폴트 메소드를 제공할 수 있다.
함수형 인터페이스 작성에는 @FunctionalInterface
애너테이션을 달아야 한다. 이 애너테이션의 목적은 크게 3가지가 있다. 첫째로 해당 클래스의 코드나 설명 문서를 읽을 이에게 그 인터페이스가 람다용으로 설계된 것임을 알려준다. 둘째로 해당 인터페이스가 추상 메소드를 오직 하나만 가지고 있어야 컴파일 되게 해준다. 마지막으로 그 결과 유지보수 과정에서 누군가 실수로 메소드를 추가하지 못하게 막아준다. 또한 함수형 인터페이스 API를 사용할 때는 서로 다른 함수형 인터페이스를 같은 위치의 인수로 받는 메소드들을 다중 정의해서는 안된다. 클라이언트에게 모호함만 안겨줄 뿐이다.