java.util.function 패키지에 미리 정의된 43개(JDK 11 기준)의 함수형 인터페이스가 집합되어 있다.
각각의 함수형 인터페이스는 기본 개념에서 약간의 변형을 통한 확장이 이루어져 있으므로
몇 가지의 주요한 함수형 인터페이스의 특성을 파악하면 된다.
첫 번째,
주요 함수형 인터페이스인 Predicate 는 어떠한 조건을 평가하기 위한 인터페이스로 제네릭 타입 T를 받아 test(T)
메서드를 통해 평가(boolean 값 반환)한다.
Predicate 의 시그니처는 T -> boolean
이다.
Predicate<Integer> isLessThan10 = i -> i < 10;
Predicate<Integer> isGreaterThan2 = i -> i > 2;
System.out.println( isLessThan10.test( 9 ) ); // true
System.out.println( isLessThan10.test( 20 ) ); // false
JDK 8 부터 도입된 디폴트 메서드를 통해 기본적 구현을 제공한다.
동작방식은 논리 연산자인 AND(&&), OR(||), NOT(!) 과 일치한다.
Method | Description |
---|---|
Predicate<T> and | 모든 값이 true인 경우 true를 반환하는 Predicate 반환 |
Predicate<T> or | 한 개의 값이라도 true인 경우 true를 반환하는 Predicate 반환 |
Predicate<T> negate | 부정(반전) 값을 반환하는 Predicate 반환 |
Predicate<Integer> isLessThan10 = i -> i < 10;
Predicate<Integer> isGreaterThan2 = i -> i > 2;
System.out.println( isGreaterThan2.and( isLessThan10 ).test( 4 ) ); // true
System.out.println( isGreaterThan2.and( isLessThan10 ).negate().test( 4 ) ); // false
System.out.println( isGreaterThan2.or( isLessThan10 ).test( 10 ) ); // true
한 가지 덧붙여 생각해볼 주제는 위와 같이 단순 값의 평가가 아닌 생각의 방식을 전환할 필요가 있다.
Predicate<Car> isBlack = ( c ) -> c.getColor() == Car.Color.BLACK;
Predicate<Car> isNotBlack = isBlack.negate();
Predicate<Car> isWhite = ( c ) -> c.getColor() == Car.Color.WHITE;
// 색상이 검은색이 아닌 차량의 이름
garage.stream()
.filter( isNotBlack )
.collect( Collectors.toList() )
.forEach( ( c ) -> System.out.println( c.getName() ) );
// 색상이 검은색, 흰색인 차량의 이름
garage.stream()
.filter( isBlack.or( isWhite ) )
.collect( Collectors.toList() )
.forEach( ( c ) -> System.out.println( c.getName() ) );
Method | Description |
---|---|
<T> Predicate<T> isEqual | 지정된 T 의 등가비교(==) 연산을 하는 Predicate 반환 |
<T> Predicate<T> not | 인수로 받는 Predicate 를 부정하는 Predicate 반환 |
// isEqual 등가비교 연산
Predicate<String> carNamePredicate = Predicate.isEqual( garage.get( 0 ).getName() );
System.out.println( "isEqual: " + carNamePredicate.test( garage.get( 1 ).getName() ) );
// not
Predicate<String> neagateCarNamePredicate = Predicate.not( carNamePredicate );
System.out.println( "not: " + neagateCarNamePredicate.test( garage.get( 1 ).getName() ) );