자바 8부터 도입되어 익명 함수(Anonymous Function)를 작성하듯 코드를 간결하게 표현할 수 있는 **람다식(Lambda Expression)**과 함수형 인터페이스를 학습합니다.
1. 람다식 핵심 용어 사전 (Glossary)
- Lambda Expression (람다식): 메소드를 하나의 간단한 식(Expression)으로 표현한 것으로, 익명 클래스의 객체를 생성하는 간결한 문법 표현입니다.
- Functional Interface (함수형 인터페이스): 단 하나의 추상 메소드만 선언되어 있는 인터페이스로,
@FunctionalInterface어노테이션으로 검증합니다. - Method Reference (메소드 참조): 람다식이 단 하나의 기존 메소드만 단순 호출할 때
Class::method형태로 극도로 축약하는 표현식입니다.
2. 자바 표준 함수형 인터페이스 4종 세트
| 인터페이스 구분 | 메소드 형상 | 매개변수 | 반환값 | 주요 역할 및 특징 |
|---|---|---|---|---|
Consumer<T> |
void accept(T t) |
⭕ (있음) | ❌ (없음) | 데이터를 소비하여 출력/처리만 수행 |
Supplier<T> |
T get() |
❌ (없음) | ⭕ (있음) | 데이터를 생성하여 공급 및 반환 |
Function<T, R> |
R apply(T t) |
⭕ (있음) | ⭕ (있음) | 매개변수 T를 받아 R 타입으로 변환 및 반환 |
Predicate<T> |
boolean test(T t) |
⭕ (있음) | ⭕ (boolean) | 조건식을 판별하여 true/false 반환 |
3. 람다식 문법 변천사 예제
import java.util.Arrays;
import java.util.List;
public class LambdaExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("홍길동", "이순신", "강감찬");
// 1. 기존 익명 클래스 방식 (복잡함)
names.forEach(new java.util.function.Consumer<String>() {
@Override
public void accept(String name) {
System.out.println("익명클래스: " + name);
}
});
// 2. 람다식 표현 방식 (간결함)
names.forEach(name -> System.out.println("람다식: " + name));
// 3. 메소드 참조 방식 (최종 축약)
names.forEach(System.out::println);
}
}
4. 자주 묻는 질문 (Q&A)
Q. 람다식 내부에서 외부 지역 변수를 수정할 수 없나요?
A. 람다식 내부에서 참조하는 외부 지역 변수는 람다 캡처링(Lambda Capturing) 메커니즘에 의해 **final 또는 사실상 final(Effectively final)**이어야 하므로 값을 직접 변경하면 컴파일 에러가 발생합니다.