java.util.function 패키지를 보면 다양한 용도의 표준 함수형 인터페이스가 담겨있다.

필요한 용도에 맞는 게 있다면, 직접 구현하지 말고 표준 함수형 인터페이스를 활하라.

그러면 API가 다루는 개념의 수가 줄어들어 익히기 더 쉬워진다.

 

java.util.function 패키지에는 총 43개의 인터페이스가 담겨 있다.

전부 기억하긴 어렵겠지만, 기본 인터페이스 6개만 기억하면 나머지를 충분히 유추해 낼 수 있다.

이 기본 인터페이스들은 모두 참조 타입용이다.

 

인터페이스 함수 시그니처
UnaryOperator<T> T apply (T t) String::toLowerCase
BinaryOperator<T> T apply(T t1, T t2) BigInteger::add
Predicate<T> boolean test (T t) Collection::isEmpty
Function<T,R> R apply (T t) Arrays::asList
Supplier<T> T get() Instant::now
Consumer<T> void accept (T t) System.out::println

 

기본 인터페이스는 기본타입인 int, long, double용으로 각 3개씩 변형이 생겨난다.

 

예를 들면 int를 받는 Predicate > IntPredicate, long을 받아 long을 반환하는 LongBinaryOperator 등이 있다.

이 변형 중 유일하게 Function의 변형만 매개변수화 되었다.

정확히는 반환 타입만 매개변수화 되었는데, 예를 들어 LongFunctional<int[]>은 long 인수를 받아 int[]을 반환한다.

 

Function 인터페이스에는 기본 타입을 반환하는 변형이 총 9개가 더 있다.

 

변형에 대해서 설명하기엔 내용이 너무 많아 나중에 정리하는 글을 기록하겠다.

 

다시 표준 함수형 인터페이스로 돌아와서.

 

표준 함수형 인터페이스 대부분은 기본 타입만 지원한다. 그렇다고 기본 함수형 인터페이스에 박싱된 기본 타입을 넣어 사용하지는 말자. 동작은 하겠지만 사용하지 않는 것을 권장한다.

 

그런데, 구조적으로 똑같은 표준 함수형 인터페이스가 있더라도 직접 작성해야만 할 때가 있다.

 

Comparator<T> 인터페이스를 떠올려보자. 구조적으로는 ToIntBiFunction<T,U>와 동일하다. 심지어 자바 라이브러리에 Comparator<T>를 추가할 당시 ToIntBiFunction<T,U>가 이미 존재했더라도 ToIntBiFunction<T,U>를 사용하면 안되었다.

 

그 이유는 Comparator<T> 인터페이스가 독자적 인터페이스이기 때문이다. 특성을 알아보면 다음과 같다.

이 중 하나 이상을 만족한다면 전용 함수형 인터페이스를 구현해야 하는 건 아닌지 고민해야 한다.

  1. 자주 쓰이며, 이름 자체가 용도를 명확히 설명해준다.
  2. 반드시 지켜야 할 규약이 있다.
  3. 유용한 디폴트 메서드를 제공할 수 있다.

전용 함수형 인터페이스를 작성하기로 했다면, 자신이 작성하는 것이 '인터페이스' 임을 명심해야한다.

아주 주의해서 설계해야 한다는 뜻이다.

 

직접 만든 함수형 인터페이스에는 항상 @FunctionalInterface 어노테이션을 사용해야한다.

그 이유는 첫 번째, 해당 클래스의 코드나 설명 문서를 읽을 이에게 그 인터페이스가 람다용으로 설계된 것임을 알려준다.

두 번째, 해당 인터페이스가 추상 메서드를 오직 하나만 가지고 있어야 컴파일되게 해준다.

세 번째, 유지보수 과정에서 누군가 실수로 메서드를 추가하지 못하게 막아준다.

 

마지막으로 함수형 인터페이스를 API에서 사용할 떄의 주의점은 다음과 같다.

서로 다른 함수형 인터페이스를 같은 위치의 인수로 받는 메서드들을 다중 정의해서는 안된다.

 

API를 설계할 떄 람다도 염두에 두어야 한다. 입력값과 반환값에 함수형 인터페이스 타입을 활용하라.
보통은 java.util.function 패키지의 표준 함수형 인터페이스를 사용하는 것이 가장 좋은 선택이다.
단, 흔하지는 않지만 직접 새로운 함수형 인터페이스를 만들어 쓰는 편이 나을 수도 있다.

 

 

 

+ Recent posts