아이템 44. 표준 함수형 인터페이스를 사용하라
템플릿 메서드 패턴 (LinkedHashMap)
protected boolean removeEldestEntry (Map .Entry <K ,V > eldest ) {
return size () > 100 ;
}
훅(hook) 메서드를 재정의해 부모 템플릿 메서드 로직을 제어한 예시.
람다를 사용하면 더 잘 해낼 수 있다.
@ FunctionalInterface interface EldestEntryRemovalFunction <K ,V > {
boolean remove (Map <K ,V > map , Map .Entry <K ,V > eldest );
}
java 표준 라이브러리에 이미 같은 모양의 인터페이스가 준비되어 있다.
직접 구현하지 말고 표준 함수형 인터페이스를 활용하라.
인터페이스
함수 시그니처
예
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개씩 변형이 있다. (18개)
SrcToResult
형태 6개 ex) LongToIntFunction
ToResult
형태 3개 ex) ToLongFunction<int[]>
BiPredicate<T, U>
BiFunction<T, U, R>
-ToLongBiFunction<T,U>
-ToIntBiFunction<T,U>
-ToDoubleBiFunction<T,U>
BiConsumer<T, U>
-ObjLongBiConsumer<T>
-ObjIntBiConsumer<T>
-ObjDoubleBiConsumer<T>
표준 함수형 인터페이스에 박싱된 기본 타입을 사용하지 말자
표준 함수형 인터페이스는 대부분 기본 타입만 지원한다.
박싱된 기본 타입을 사용하면 처참히 느려질 수 있다.
Comparator<T>는 ToIntBiFunction<T,U>와 동일하다.
하지만 독자적인 인터페이스로 남은 이유가 3가지 있다.
자주 쓰이며, 이름 자체가 용도를 명확히 설명해준다.
반드시 따라야 하는 규약이 있다.
유용한 디폴트 메서드를 제공할 수 있다.
@FunctionalInterface 애너테이션의 목적
해당 인터페이스가 람다용으로 설계된 것임을 알려준다.
추상 메서드 하나만 가지고 있어야 컴파일 된다.
그러므로 유지보수 과정에서 메서드를 추가하지 못하게 막아준다.
주의점: 다른 함수형 인터페이스를 같은 위치의 인수로 받는 메서드를 다중정의하지 말자.
<T > Future <T > submit (Callable <T > task );
Future <?> submit (Runnable task );
클라이언트에게 모호함을 안겨주며, 이로 인해 실제로 문제가 생긴다.