✅ 1. 함수형 인터페이스란?
- 추상 메서드가 단 하나만 있는 인터페이스
- 람다식을 사용하려면 반드시 함수형 인터페이스 필요
- @FunctionalInterface 사용 (컴파일 타임 체크)
@FunctionalInterface
interface MyFunction {
int apply(int x);
}
✅ 2. 제네릭 도입 전/후 비교
방식코드 재사용타입 안정성특징
StringFunction, NumberFunction 등 별도 정의 | ❌ | ✅ | 타입마다 따로 만들어야 함 |
ObjectFunction | ✅ | ❌ | 다운캐스팅 필요, 타입 불안정 |
GenericFunction<T, R> | ✅ | ✅ | 타입 안정성 + 재사용성 확보 |
제네릭 도입후 아래와같이 편리하게 사용 가능하다.
@FunctionalInterface
interface GenericFunction<T, R> {
R apply(T t);
}
GenericFunction<String, Integer> strLength = s -> s.length();
System.out.println(strLength.apply("hello")); // 5
✅ 3. 람다와 타겟 타입
- 람다는 타입이 없다 → 대입되는 함수형 인터페이스에 따라 타입이 정해짐.
- FunctionA와 FunctionB가 메서드 시그니처가 같더라도 타입이 다르면 대입 불가.
- 따라서 불필요한 중복을 방지하고, 타입 호환성을 보장하기 위해 자바는 기본 함수형 인터페이스를 제공한다.
✅ 4. 자바 기본 함수형 인터페이스
① Function<T, R> — 입력 O, 반환 O
Function<String, Integer> length = s -> s.length();
System.out.println(length.apply("Java")); // 4
② Consumer<T> — 입력 O, 반환 X
Consumer<String> print = s -> System.out.println("Hello " + s);
print.accept("World"); // Hello World
③ Supplier<T> — 입력 X, 반환 O
Supplier<Double> random = () -> Math.random();
System.out.println(random.get()); // ex) 0.7282
④ Runnable — 입력 X, 반환 X
Runnable run = () -> System.out.println("Running!");
run.run(); // Running!
✅ 5. 특화 함수형 인터페이스
① Predicate<T> — 조건 판별 (boolean 반환)
Predicate<Integer> isEven = i -> i % 2 == 0;
System.out.println(isEven.test(4)); // true
대체 가능: Function<T, Boolean> → 하지만 의미 명확성을 위해 Predicate 권장
② UnaryOperator<T> — 같은 타입 단항 연산
UnaryOperator<String> toUpper = s -> s.toUpperCase();
System.out.println(toUpper.apply("java")); // JAVA
대체 가능: Function<T, T> → 하지만 의미 명확성을 위해 UnaryOperator 권장
③ BinaryOperator<T> — 같은 타입 이항 연산
BinaryOperator<Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(3, 4)); // 7
대체 가능: BiFunction<T, T, T>
✅ 6. 입력 2개 이상: Bi 계열
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.apply(10, 20)); // 30
BiPredicate<String, Integer> isLonger = (s, len) -> s.length() > len;
System.out.println(isLonger.test("hello", 3)); // true
✅ 7. 기본형 함수형 인터페이스
- 성능 최적화를 위해 제공됨 (오토박싱/언박싱 방지)
IntFunction<String> intToStr = i -> "Value: " + i;
System.out.println(intToStr.apply(10)); // Value: 10
ToIntFunction<String> strLen = s -> s.length();
System.out.println(strLen.applyAsInt("Java")); // 4
IntUnaryOperator doubleIt = i -> i * 2;
System.out.println(doubleIt.applyAsInt(5)); // 10
🎯 핵심 요약 정리
상황사용 인터페이스
데이터 변환 | Function<T, R> |
데이터 소비 | Consumer<T> |
데이터 공급 | Supplier<T> |
단순 실행 | Runnable |
조건 검사 | Predicate<T> |
같은 타입 단항 연산 | UnaryOperator<T> |
같은 타입 이항 연산 | BinaryOperator<T> |
두 인자 처리 | BiFunction<T,U,R>, BiPredicate, BiConsumer 등 |
기본형 처리 | IntFunction, ToIntFunction, IntPredicate 등 |
'Java' 카테고리의 다른 글
[Java] 김영한의 실전 자바 - 고급 3편 섹션4,5 람다활용,익명클래스와의 차이 (+정적 팩토리 메서드) (0) | 2025.04.07 |
---|---|
[Java] 익명 클래스 vs 람다: 자바 람다, 내부에선 어떤 일이 벌어질까?(Java Lambda & invokedynamic) (0) | 2025.04.03 |
[Java] 김영한의 실전 자바 - 고급 3편 섹션1,2 람다 (2) | 2025.03.31 |
[Java] 김영한의 실전 자바 - 고급 2편 섹션15 HTTP 서버 활용 (0) | 2024.12.02 |
[Java] 김영한의 실전 자바 - 고급 2편 섹션14 애노테이션 (4) | 2024.11.28 |