반응형
📌 함수형 인터페이스란 무엇인가?
자바 8에서 가장 혁신적인 변화 중 하나가 바로 함수형 인터페이스(Functional Interface)입니다. 단순하게 말하면:
"단 하나의 추상 메서드만 가진 인터페이스"
이렇게 단순한 개념이지만, 이것이 자바에서 람다식과 함수형 프로그래밍을 가능하게 한 핵심 요소입니다.
💡 함수형 인터페이스의 특징
- 오직 하나의 추상 메서드만 포함
@FunctionalInterface
어노테이션으로 명시 가능 (선택사항)- 디폴트 메서드와 정적 메서드는 개수 제한 없음
- 람다식으로 간단하게 구현 가능
@FunctionalInterface
interface SimpleFunction {
// 단 하나의 추상 메서드
void execute();
// 디폴트 메서드는 여러 개 가능
default void printInfo() {
System.out.println("이것은 함수형 인터페이스입니다.");
}
// 정적 메서드도 여러 개 가능
static void describe() {
System.out.println("함수형 인터페이스의 정적 메서드");
}
}
🛠️ 자바에서 제공하는 주요 함수형 인터페이스
자바 8부터 java.util.function
패키지에서 다양한 함수형 인터페이스를 제공합니다.
1. Consumer<T> - 소비자
데이터를 받아서 사용만 하고 반환하지 않는 인터페이스
Consumer<String> printer = message -> System.out.println(message);
printer.accept("안녕하세요!"); // 출력: 안녕하세요!
2. Supplier<T> - 공급자
아무런 입력 없이 데이터를 생성하여 반환하는 인터페이스
Supplier<LocalDateTime> now = () -> LocalDateTime.now();
System.out.println(now.get()); // 현재 시간 출력
3. Function<T, R> - 함수
T 타입 인자를 받아 R 타입 결과를 반환하는 인터페이스
Function<String, Integer> strLength = str -> str.length();
System.out.println(strLength.apply("함수형 프로그래밍")); // 출력: 8
4. Predicate<T> - 조건식
T 타입 인자를 평가하여 boolean 값을 반환하는 인터페이스
Predicate<Integer> isPositive = num -> num > 0;
System.out.println(isPositive.test(10)); // 출력: true
System.out.println(isPositive.test(-5)); // 출력: false
🔍 함수형 인터페이스의 다양한 변형들
기본 함수형 인터페이스 외에도 성능 최적화를 위한 특수 버전들이 존재합니다:
- 기본형 특화: IntPredicate, LongConsumer 등
- 이항 연산자: BiFunction, BiConsumer 등
- 복합 연산: BinaryOperator, UnaryOperator 등
// 기본형 특화 예시
IntPredicate evenNumbers = n -> n % 2 == 0;
System.out.println(evenNumbers.test(4)); // true
// 이항 연산자 예시
BiFunction<Integer, Integer, String> formatter =
(a, b) -> String.format("%d와 %d의 합은 %d입니다.", a, b, a + b);
System.out.println(formatter.apply(10, 20)); // 10와 20의 합은 30입니다.
🚀 커스텀 함수형 인터페이스 만들기
필요에 따라 직접 함수형 인터페이스를 정의할 수도 있습니다.
@FunctionalInterface
interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}
// 사용 예시
TriFunction<Integer, Integer, Integer, Integer> sum3 =
(a, b, c) -> a + b + c;
System.out.println(sum3.apply(10, 20, 30)); // 출력: 60
🔄 메서드 참조로 더 간결하게
람다식이 단순히 기존 메서드를 호출하는 경우, 메서드 참조(Method Reference)를 사용하면 코드가 더 간결해집니다.
// 람다식
Consumer<String> printer = s -> System.out.println(s);
// 메서드 참조로 더 간결하게
Consumer<String> betterPrinter = System.out::println;
메서드 참조의 4가지 유형:
- 정적 메서드 참조:
ClassName::staticMethodName
- 인스턴스 메서드 참조:
instance::methodName
- 특정 타입의 인스턴스 메서드 참조:
ClassName::methodName
- 생성자 참조:
ClassName::new
💪 실전에서 함수형 인터페이스 활용하기
함수형 인터페이스는 특히 컬렉션 처리와 스트림 API에서 빛을 발합니다:
List<String> names = Arrays.asList("김자바", "이스프링", "박함수", "최람다");
// Predicate로 필터링
Predicate<String> startsWithK = name -> name.startsWith("김");
List<String> kimFamily = names.stream()
.filter(startsWithK)
.collect(Collectors.toList());
// Function으로 변환
Function<String, Integer> nameLength = String::length;
List<Integer> nameLengths = names.stream()
.map(nameLength)
.collect(Collectors.toList());
// Consumer로 출력
Consumer<String> greet = name -> System.out.println("안녕하세요, " + name + "님!");
names.forEach(greet);
📝 함수형 인터페이스의 장점
- 코드 간결성 - 익명 클래스보다 훨씬 간결한 문법
- 재사용성 증가 - 함수를 일급 객체처럼 다룰 수 있음
- 테스트 용이성 - 작은 단위의 기능을 분리하여 테스트하기 쉬움
- 병렬 처리 지원 - 스트림 API와 결합하여 병렬 처리 가능
- 유지보수성 향상 - 선언적 프로그래밍으로 가독성 증가
✅ 정리
함수형 인터페이스는 자바의 객체지향 프로그래밍과 함수형 프로그래밍을 연결하는 다리 역할을 합니다. 단 하나의 추상 메서드만 가지는 단순한 개념이지만, 이를 통해 람다식과 메서드 참조를 활용할 수 있어 코드를 훨씬 더 간결하고 표현력 있게 만들 수 있습니다.
함수형 인터페이스를 이해하고 적재적소에 활용한다면, 여러분의 자바 코드는 더욱 현대적이고 효율적으로 진화할 것입니다!
반응형
'백엔드' 카테고리의 다른 글
Java 제네릭 메소드 완벽 가이드: 코드의 재사용성과 안전성을 한번에! (0) | 2025.03.13 |
---|---|
Java 컬렉션 프레임워크 정리 (0) | 2025.03.06 |
람다식(Lambda) 4가지 유형 총정리 (0) | 2025.03.05 |
자바와 스프링, 스프링부트 차이와 정리 (0) | 2025.02.14 |
💻 자바 메소드 오버로딩이란 무엇인가? (2) | 2025.01.17 |