Java 8의 Function과 Predicate란?
Function과 Predicate는 모두 Java 8에서 도입된 함수형 인터페이스(Functional Interface)로, 자바에서 함수형 프로그래밍을 구현하기 위해 제공됩니다.
Function 인터페이스는 값의 변환(transformation)을 수행하는 데 사용됩니다. 하나의 인자를 받아 그에 대응하는 결과를 생성합니다. 반면 Predicate 역시 하나의 인자만 받을 수 있지만, 오직 boolean 값(true/false)만 반환할 수 있습니다. 즉, 주어진 조건을 검사(test)하는 용도로 사용됩니다.
Function vs Predicate 비교표
| 번호 | 구분 | Function | Predicate |
|---|---|---|---|
| 1 | 기본 구조 | 두 개의 타입 매개변수를 가집니다. 첫 번째는 입력(인자) 타입, 두 번째는 반환 타입을 나타냅니다. | 하나의 타입 매개변수만 가지며, 이는 입력(인자) 타입을 나타냅니다. |
| 2 | 반환 타입 | 모든 타입의 값을 반환할 수 있습니다. | boolean 값만 반환할 수 있습니다. |
| 3 | 추상 메서드 | apply() 추상 메서드를 가집니다. | test() 추상 메서드를 가집니다. |
| 4 | 주요 용도 | 값의 변환 및 새로운 결과 반환에 사용됩니다. | 조건 검사 및 필터링에 사용됩니다. |
Predicate 예제
public class Main {
public static void main(String args[]) {
List<Integer> numList = new ArrayList<>();
numList.add(5);
numList.add(10);
Predicate<Integer> pred = i -> i > 5;
numList.stream().filter(pred).forEach(i -> System.out.println(i));
}
}
위 예제에서 Predicate는 람다 표현식 i -> i > 5를 통해 각 숫자가 5보다 큰지 검사합니다. 스트림의 filter() 메서드는 이 조건을 통과한 요소만 남기므로, 실행 결과로 10만 출력됩니다.
Function 예제
public class Main {
public static void main(String args[]) {
List<Integer> numList = new ArrayList<>();
numList.add(78);
numList.add(10);
Function<Integer, Integer> fun = i -> i / 2;
numList.stream().map(fun).forEach(System.out::println);
}
}
위 예제에서 Function은 람다 표현식 i -> i / 2를 통해 각 숫자를 2로 나누어 변환합니다. 스트림의 map() 메서드가 이 변환 로직을 적용하므로, 실행 결과로 39와 5가 출력됩니다.
정리
핵심을 요약하면, Function은 "입력을 무엇으로 변환할 것인가"를 다루고, Predicate는 "조건이 참인가 거짓인가"를 판단합니다. 스트림 API에서 map()에는 Function이, filter()에는 Predicate가 사용된다는 점을 기억하면 두 인터페이스의 역할을 쉽게 구분할 수 있습니다.