ch13_람다와함수형
통합 문서입니다.
1. 람다와 함수형 프로그래밍
람다와 함수형 프로그래밍
학습 목표
- 람다식과 함수형 인터페이스의 관계를 정확히 이해할 수 있다.
Predicate,Function,Consumer,Supplier를 상황별로 사용할 수 있다.- 부작용을 줄인 함수형 스타일로 가독성과 테스트 용이성을 높일 수 있다.
1. 람다의 본질
람다는 익명 함수 문법이지만, Java에서는 결국 함수형 인터페이스 구현체다.
Comparator<String> cmp = (a, b) -> a.length() - b.length();
핵심:
- 동작(behavior)을 값처럼 전달
- 전략을 외부에서 주입
- 보일러플레이트 감소
2. 함수형 인터페이스
추상 메소드가 정확히 하나인 인터페이스.
@FunctionalInterface
interface Calculator {
int calc(int a, int b);
}
람다식은 해당 추상 메소드 구현으로 매핑된다.
3. 표준 함수형 인터페이스
Predicate<T>: T -> booleanFunction<T, R>: T -> RConsumer<T>: T 소비, 반환 없음Supplier<T>: 입력 없이 T 제공UnaryOperator<T>,BinaryOperator<T>: Function 특수형
예:
Predicate<String> notBlank = s -> s != null && !s.isBlank();
Function<String, Integer> length = String::length;
Consumer<String> out = System.out::println;
Supplier<UUID> uuid = UUID::randomUUID;
4. 람다 문법 포인트
(파라미터) -> 표현식
(파라미터) -> { 문장; return 값; }
규칙:
- 파라미터 타입은 대부분 추론 가능
- 파라미터 1개면 괄호 생략 가능
- 본문이 1식이면 중괄호/return 생략 가능
5. 메소드 참조
람다를 더 간결하게 표현하는 문법.
종류:
ClassName::staticMethodinstance::instanceMethodClassName::instanceMethodClassName::new(생성자 참조)
6. 함수 조합(Composition)
Function은 조합 메소드를 제공한다.
Function<String, String> trim = String::trim;
Function<String, String> lower = String::toLowerCase;
Function<String, String> normalize = trim.andThen(lower);
작은 함수들을 조합하면 재사용성과 테스트 용이성이 높아진다.
7. 부작용과 불변성
함수형 스타일 핵심은 “부작용 최소화”다.
지양:
- 람다 내부에서 외부 가변 상태 수정
- 전역 상태 누적
권장:
- 입력 -> 출력 변환 중심
- 불변 데이터 구조와 조합
8. 람다와 예외 처리
표준 함수형 인터페이스는 checked 예외를 직접 던지기 어렵다.
대안:
- 람다 내부 try-catch
- 예외 래핑 유틸 함수
- checked를 runtime으로 의미 있게 변환
9. 디버깅/가독성 전략
- 람다 본문이 길어지면 별도 메소드로 분리
- 의미 있는 변수명으로 중간 단계 분리
- 메소드 참조 남용 금지(오히려 이해 어려운 경우 존재)
10. 실무 패턴
- 유효성 검사 파이프라인
- 정책(할인/필터) 주입
- 이벤트 핸들러 등록
- Stream 연산 함수 전달
11. 정리
- 람다는 문법 단축이 아니라 동작 전달 모델이다.
- 함수형 인터페이스와 함수 조합을 이해하면 코드 유연성이 크게 올라간다.
- 부작용을 줄이는 방향으로 쓰는 것이 함수형 스타일의 핵심이다.
2. 문제
문제
ch13 범위(람다, 함수형 인터페이스, 메소드 참조, 함수 조합) 문제입니다.
A. 람다 기초
Calculator함수형 인터페이스를 만들고 덧셈 람다를 구현하시오.- 같은 인터페이스로 뺄셈/곱셈/나눗셈 람다를 구현하시오.
- 익명 클래스 구현과 람다 구현을 비교하시오.
B. 표준 함수형 인터페이스
Predicate<String>로 빈 문자열 필터를 구현하시오.Function<String, Integer>로 문자열 길이 변환을 구현하시오.Consumer<String>로 로그 출력 함수를 작성하시오.Supplier<UUID>로 랜덤 ID를 생성하시오.
C. 메소드 참조
s -> s.length()를String::length로 바꾸시오.x -> System.out.println(x)를 메소드 참조로 바꾸시오.- 생성자 참조(
User::new)를 사용해 객체 리스트를 생성하시오.
D. 함수 조합
- trim -> lowercase -> prefix 추가 함수를 조합하시오.
Predicate의and,or,negate를 활용해 복합 조건 필터를 작성하시오.- 리스트 전처리 파이프라인을 함수 조합으로 구성하시오.
E. 실무 시나리오
- 할인 정책 인터페이스를 함수형으로 설계하고 런타임에 교체하시오.
- 입력 검증 정책을 람다 리스트로 구성해 순차 적용하시오.
- 이벤트 콜백 구조를 람다로 단순화하시오.
F. 챌린지
- 체크 예외를 다루는 람다 래퍼 유틸을 구현하시오.
- 부작용이 있는 람다와 없는 람다를 비교하고 테스트 코드를 작성하시오.
- Stream 파이프라인과 결합해 람다 중심 데이터 처리 코드를 작성하시오.
제출 체크리스트
- 람다 본문이 지나치게 길지 않은가?
- 함수형 인터페이스 선택이 목적과 맞는가?
- 메소드 참조가 오히려 가독성을 해치지 않는가?
- 외부 가변 상태를 불필요하게 변경하지 않았는가?