java.util.function 패키지에는 여러가지 함수형 인터페이스들이 정의되어 있다.
그중에서 가장 기본적인 함수형 인터페이스는 다음과 같다.
매개변수와 반환값의 유무에 따라 4개의 함수형 인터페이스가 정의되어 있다.
Predicate는 Function의 변형으로, 반환타입이 boolean이라는 점이 다르다.
Predicate는 조건식을 람다식으로 표현하는데 사용된다.
// Predicate 사용예시
Predicate<String> isEmptyStr = s -> s.length() == 0;
String s = "";
if(isEmptyStr.test(s)) // if(s.length() == 0)
System.out.println("This is an empty String.");
매개변수의 개수가 2개인 함수형 인터페이스는 이름 앞에 접두사 'Bi'가 붙는다.
두 개 이상의 매개변수를 갖는 함수형 인터페이스가 필요하다면, 직접 만들어야 한다.
3개의 매개변수를 갖는 함수형 인터페이스를 선언한다면 아래와 같을 것이다.
@FunctionalInterface
interface TriFunction<T,U,V,R> {
R apply(T t, U u, V v);
}
Function의 또 다른 변형으로 UnaryOperator와 BinaryOprerator가 있다.
매개변수의 타입과 반환타입의 타입이 모두 일치한다는 점 이외에는 Function과 같다.
컬렉션 프레임웍의 인터페이스에는 함수형 인터페이스를 사용하는 다수의 디폴트 메서드가
추가 되었다.
// List 선언
ArrayList<Integer> list = new ArrayList<>();
for(int i=0; i<10; i++){
list.add(i);
}
// list의 모든 요소를 출력
list.forEach(i -> System.out.print(i + ",") );
list.removeIf(x -> x%2==0 || x%3==0);
list.replaceAll(i -> i*10);
Map<String, String> map = new HashMap<>();
map.put("1","1");
map.put("2","2");
map.put("3","3");
map.put("4","4");
map.forEach((k,v) -> System.out.print("{" + k + "," + v + "},"));
매개변수와 반환값이 지네릭 타입일 경우, 박싱(boxing)과 언박싱(unboxing)횟수가 증가하여 성능이
좋지 못하다. 기본형 대신 래퍼(wrapper)클래스를 사용하지 않고도 처리할 수 있는 함수형 인터페이스가 제공된다.
함수형 인터페이스인 Function과 Predicate에 정의된 메서드는 아래와 같다.
Function의 합성은 어떤 함수를 먼저 적용하는지에 따라 달라진다. 함수 x와 z가 있다고 가정하였을때,
x.andthen(z)는 함수 x를 먼저 적용하고, 그 다음에 함수 z를 적용하는 것이다.
// andThen() 사용예시
Function<String, String> f = (s) -> Integer.parseInt(s, 16);
Function<Integer, String> g = (i) -> Integer.toBinaryString(i);
Function<String, String> h = f.andThen(g);
위 함수에 문자열 "FF"를 입력하면, 결과로 "11111111"을 얻는다.
"FF"문자열이 먼저 숫자 255로 변환되고, 255는 문자열 "11111111"로 변환되기 때문에
"FF"문자열을 입력으로 주었을때, "11111111"이 반환되는 것이다.
compose( )는 andThen( )과 반대로, 함수 x와 z가 있다고 가정하였을때, x.compose(z)는 함수 z를 먼저 적용하고, 그 다음에 함수 x를 적용하는 것이다.
// compose() 사용예시
Function<Integer, String> g = (i) -> Integer.toBinaryString(i);
Function<String, Integer> f = (s) -> Integer.parseInt(s, 16);
Function<Integer, Integer> h = f.compose(g);
위 함수에 숫자 10을 입력하면 결과로 16을 얻는다.
숫자 2를 입력으로 주면, 2진 문자열인 "10"으로 변환되고, 2진 문자열 "10"은 숫자 16으로 변환되어,
숫자 2를 입력으로 주었을때, 16을 반환받게 된다.