람다식은 익명 함수(이름 없는 함수)를 간단하게 표현하는 방식이다. 주로 함수형 인터페이스(Functional Interface)의 구현을 간결하게 작성할 때 사용한다.
// 기존 방식 (익명 클래스)
Runnable run1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello from Runnable!");
}
};
// 람다식 사용
Runnable run2 = () -> System.out.println("Hello from Lambda!");
람다식을 사용하려면 인터페이스에 추상 메서드가 하나만 있어야 한다. 이를 함수형 인터페이스라고 한다.
@FunctionalInterface
interface MyFunction {
void doSomething();
}
※ @FunctionalInterface는 선택사항이지만, 두 개 이상 메서드가 생기면 컴파일 오류를 발생시켜 실수를 방지할 수 있다.
(매개변수) -> { 실행문 }
// 매개변수 X, 리턴 X
() -> System.out.println("Hello");
// 매개변수 1개, 괄호 생략 가능
x -> System.out.println(x);
// 매개변수 2개 이상
(x, y) -> {
int sum = x + y;
return sum;
};
// 리턴문만 있는 경우 중괄호와 return 생략 가능
(x, y) -> x + y;
| 인터페이스 | 설명 | 메서드 시그니처 |
|---|---|---|
Runnable | 매개변수 없고 반환값 없음 | void run() |
Consumer<T> | T를 받아 소비, 반환값 없음 | void accept(T t) |
Supplier<T> | 매개변수 없고 T를 반환 | T get() |
Function<T,R> | T를 받아 R을 반환 | R apply(T t) |
Predicate<T> | T를 받아 true/false 반환 | boolean test(T t) |
List<String> names = Arrays.asList("Java", "Python", "JavaScript");
names.stream()
.filter(name -> name.startsWith("J"))
.forEach(System.out::println);
List<String> list = Arrays.asList("Banana", "Apple", "Cherry");
list.sort((s1, s2) -> s1.compareTo(s2));
System.out.println(list);
코드가 간결해진다
함수형 프로그래밍을 지원
익명 내부 클래스보다 가독성이 좋다
디버깅 어려움
복잡한 로직에는 오히려 가독성 저하