
함수형 인터페이스는 오직 하나의 메서드만 가지는 인터페이스이다. 자바에서는 이 인터페이스를 통해 함수를 값처럼 전달할 수 있으며, 람다 표현식의 대상이 되는 타입이기도 하다. 자바 8 이전에는 익명 클래스를 사용해야 해서 코드가 복잡하고 길어졌다. 예를 들어 두 수를 더하는 연산을 표현할 때, 람다를 사용하지 않으면 다음과 같이 작성해야 한다.
BinaryOperator<Integer> add = new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer x, Integer y) {
return x + y;
}
};
람다 표현식은 이름 없이 기능만 정의하는 익명 함수를 간단하게 표현하는 문법이다. 자바는 함수 자체를 값처럼 쓸 수 없기 때문에, 함수형 인터페이스를 이용해 함수를 대신 전달하고, 이때 람다 표현식을 구현체처럼 사용할 수 있다. 예를 들어, 자바 8부터는 람다 표현식을 사용해 익명함수를 간결하게 작성할 수 있다.
BinaryOperator<Integer> add = (x, y) -> x + y;
람다 표현식에서 메서드 한 개만 호출하는 경우, 메서드 레퍼런스를 사용하면 코드를 더 짧고 보기 쉽게 만들 수 있다. 이때 :: 기호로 메서드를 직접 참조한다.
| 유형 | 표현 | 설명 |
|---|---|---|
| 정적 메서드 참조 | ClassName::staticMethod | 정적 메서드 호출 |
| 타입의 인스턴스 메서드 참조 | ClassName::instanceMethod | 람다 매개변수를 수신자로 사용 |
| 객체의 인스턴스 메서드 참조 | object::instanceMethod | 특정 객체의 메서드 참조 |
| 생성자 참조 | ClassName::new | 생성자 호출 |
정적 메서드 참조 —
ClassName::staticMethod
정적 메서드를 참조하는 형태로, 다음과 같이 사용한다.
list.stream()
.map(StringUtils::capitalize);
특정 타입의 인스턴스 메서드 참조 —
ClassName::instanceMethod
해당 타입의 객체가 주어졌을 때 호출 가능한 인스턴스 메서드를 참조한다.
list.stream()
.map(String::toUpperCase);
이는 s -> s.toUpperCase()와 동일한 표현이다. 스트림의 요소가 String 타입인 경우 유용하게 사용된다.
특정 객체의 인스턴스 메서드 참조 —
object::instanceMethod
이미 생성된 객체의 메서드를 참조하는 방식이다.
MyFormatter formatter = new MyFormatter();
list.stream()
.map(formatter::format);
객체를 기반으로 한 고정된 메서드를 사용할 경우 적합하다.
생성자 참조 —
ClassName::new
객체를 생성하는 생성자를 참조할 수 있다. 주로 스트림에서 변환 작업 시 사용된다.
list.stream()
.map(User::new);
이 경우 User(String name) 생성자가 존재해야 하며, s -> new User(s)를 간결하게 표현한 형태이다.
함수 디스크립터는 함수형 인터페이스가 어떤 입력값을 받고 어떤 값을 반환하는지를 간단하게 표현한 것이다. 람다 표현식은 이 형태(입력 → 출력)가 일치하는 인터페이스에 자동으로 연결된다.
| 인터페이스 | 디스크립터 | 설명 |
|---|---|---|
Predicate<T> | (T) -> boolean | 입력값을 평가하여 true/false 반환 |
Consumer<T> | (T) -> void | 입력값을 소비하고 반환하지 않음 |
Function<T, R> | (T) -> R | 입력값을 변환하여 결과 반환 |
Supplier<T> | () -> T | 입력 없이 값 생성 |
BiPredicate<T, U> | (T, U) -> boolean | 두 입력값을 평가하여 boolean 반환 |
BiConsumer<T, U> | (T, U) -> void | 두 입력값을 받아 처리 |
BiFunction<T, U, R> | (T, U) -> R | 두 입력값을 받아 결과 반환 |