말귀 알아듣기.zip

[Java] java.util.function 함수형 인터페이스 종류 완벽 정리 (Consumer, Supplier, Function, Predicate)

zippy 2026. 4. 19. 01:25
반응형

☕ java.util.function 패키지 완벽 정리

Java 8부터 도입된 java.util.function 패키지는 람다식과 메서드 참조를 활용한 함수형 프로그래밍을 지원하는 다양한 함수형 인터페이스를 제공합니다. 이 글에서는 각 인터페이스의 역할과 사용법을 한눈에 정리합니다.


📑 목차

  1. 함수형 인터페이스란?
  2. 기본 함수형 인터페이스
  3. 이항(Binary) 함수형 인터페이스
  4. 단항(Unary) 연산자
  5. 정수 타입(int) 특화 인터페이스
  6. 롱 타입(long) 특화 인터페이스
  7. 더블 타입(double) 특화 인터페이스
  8. Boolean 특화 인터페이스
  9. 반환값 특화 인터페이스
  10. 객체-기본타입 혼합 인터페이스
  11. 사용 예시
  12. 주요 특징 정리
  13. 마무리

📌 1. 함수형 인터페이스란?

함수형 인터페이스(Functional Interface)란 단 하나의 추상 메서드만을 가지는 인터페이스입니다. @FunctionalInterface 어노테이션을 붙여 명시적으로 선언하며, 람다식 또는 메서드 참조로 간결하게 구현할 수 있습니다. Java의 Stream API와도 긴밀하게 연동되어 실무에서 매우 폭넓게 사용됩니다.


✅ 2. 기본 함수형 인터페이스

가장 기본이 되는 4가지 인터페이스입니다. 대부분의 함수형 인터페이스는 이 4가지를 기반으로 확장됩니다.

인터페이스 제네릭 타입 설명
Consumer<T> <T> 단일 입력 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
Supplier<T> <T> 결과를 공급하는 작업을 나타냅니다. (입력 없음)
Function<T,R> <T,R> 한 개의 인수를 받아서 결과를 생성하는 함수를 나타냅니다.
Predicate<T> <T> 한 개의 인수에 대한 boolean 값 함수(조건)를 나타냅니다.

✅ 3. 이항(Binary) 함수형 인터페이스

두 개의 인수를 받아 처리하는 인터페이스입니다.

인터페이스 제네릭 타입 설명
BiConsumer<T,U> <T,U> 두 개의 입력 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
BiFunction<T,U,R> <T,U,R> 두 개의 인수를 받아서 결과를 생성하는 함수를 나타냅니다.
BiPredicate<T,U> <T,U> 두 개의 인수에 대한 boolean 값 함수(조건)를 나타냅니다.
BinaryOperator<T> <T> 동일한 타입의 두 개 피연산자에 대한 작업을 나타내며, 같은 타입의 결과를 생성합니다.

✅ 4. 단항(Unary) 연산자

하나의 피연산자를 받아 동일한 타입의 결과를 반환하는 연산자 인터페이스입니다.

인터페이스 제네릭 타입 설명
UnaryOperator<T> <T> 단일 피연산자에 대한 작업을 나타내며, 피연산자와 같은 타입의 결과를 생성합니다.
IntUnaryOperator - int 피연산자에 대한 작업을 나타내며, int 결과를 생성합니다.
LongUnaryOperator - long 피연산자에 대한 작업을 나타내며, long 결과를 생성합니다.
DoubleUnaryOperator - double 피연산자에 대한 작업을 나타내며, double 결과를 생성합니다.

✅ 5. 정수 타입(int) 특화 인터페이스

기본 타입 int에 특화된 인터페이스로, 박싱/언박싱 오버헤드 없이 성능 최적화를 제공합니다.

인터페이스 제네릭 타입 설명
IntConsumer - 단일 int 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
IntSupplier - int 값의 결과를 공급하는 작업을 나타냅니다.
IntFunction<R> <R> int 값 인수를 받아서 결과를 생성하는 함수를 나타냅니다.
IntPredicate - 단일 int 값 인수에 대한 boolean 값 함수(조건)를 나타냅니다.
IntBinaryOperator - 두 개의 int 값 피연산자에 대한 작업을 나타내며, int 결과를 생성합니다.
IntToDoubleFunction - int 값 인수를 받아서 double 값 결과를 생성하는 함수를 나타냅니다.
IntToLongFunction - int 값 인수를 받아서 long 값 결과를 생성하는 함수를 나타냅니다.

✅ 6. 롱 타입(long) 특화 인터페이스

기본 타입 long에 특화된 인터페이스입니다.

인터페이스 제네릭 타입 설명
LongConsumer - 단일 long 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
LongSupplier - long 값의 결과를 공급하는 작업을 나타냅니다.
LongFunction<R> <R> long 값 인수를 받아서 결과를 생성하는 함수를 나타냅니다.
LongPredicate - 단일 long 값 인수에 대한 boolean 값 함수(조건)를 나타냅니다.
LongBinaryOperator - 두 개의 long 값 피연산자에 대한 작업을 나타내며, long 결과를 생성합니다.
LongToDoubleFunction - long 값 인수를 받아서 double 값 결과를 생성하는 함수를 나타냅니다.
LongToIntFunction - long 값 인수를 받아서 int 값 결과를 생성하는 함수를 나타냅니다.

✅ 7. 더블 타입(double) 특화 인터페이스

기본 타입 double에 특화된 인터페이스입니다.

인터페이스 제네릭 타입 설명
DoubleConsumer - 단일 double 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
DoubleSupplier - double 값의 결과를 공급하는 작업을 나타냅니다.
DoubleFunction<R> <R> double 값 인수를 받아서 결과를 생성하는 함수를 나타냅니다.
DoublePredicate - 단일 double 값 인수에 대한 boolean 값 함수(조건)를 나타냅니다.
DoubleBinaryOperator - 두 개의 double 값 피연산자에 대한 작업을 나타내며, double 결과를 생성합니다.
DoubleToIntFunction - double 값 인수를 받아서 int 값 결과를 생성하는 함수를 나타냅니다.
DoubleToLongFunction - double 값 인수를 받아서 long 값 결과를 생성하는 함수를 나타냅니다.

✅ 8. Boolean 특화 인터페이스

인터페이스 제네릭 타입 설명
BooleanSupplier - boolean 값의 결과를 공급하는 작업을 나타냅니다.

✅ 9. 반환값 특화 인터페이스

입력 타입에 관계없이 특정 기본 타입으로 결과를 반환하는 인터페이스입니다.

인터페이스 제네릭 타입 설명
ToDoubleFunction<T> <T> 단일 인수를 받아서 double 값 결과를 생성하는 함수를 나타냅니다.
ToDoubleBiFunction<T,U> <T,U> 두 개의 인수를 받아서 double 값 결과를 생성하는 함수를 나타냅니다.
ToIntFunction<T> <T> 단일 인수를 받아서 int 값 결과를 생성하는 함수를 나타냅니다.
ToIntBiFunction<T,U> <T,U> 두 개의 인수를 받아서 int 값 결과를 생성하는 함수를 나타냅니다.
ToLongFunction<T> <T> 단일 인수를 받아서 long 값 결과를 생성하는 함수를 나타냅니다.
ToLongBiFunction<T,U> <T,U> 두 개의 인수를 받아서 long 값 결과를 생성하는 함수를 나타냅니다.

✅ 10. 객체-기본타입 혼합 인터페이스

객체 타입과 기본 타입 인수를 함께 받는 Consumer 계열 인터페이스입니다.

인터페이스 제네릭 타입 설명
ObjIntConsumer<T> <T> 객체 값과 int 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
ObjLongConsumer<T> <T> 객체 값과 long 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.
ObjDoubleConsumer<T> <T> 객체 값과 double 값 인수를 받고 결과를 반환하지 않는 작업을 나타냅니다.

💡 11. 사용 예시

Consumer 예시

입력값을 받아 소비(출력 등)하고 반환값 없음

Consumer<String> print = System.out::println;
print.accept("Hello World");  // 출력: Hello World

Supplier 예시

인수 없이 값을 공급

Supplier<String> greeting = () -> "Hello, Java!";
System.out.println(greeting.get());  // 출력: Hello, Java!

Function 예시

입력을 받아 변환 후 반환

Function<Integer, Integer> square = x ->  * ;
int result = square.apply(5);  // 결과: 25

Predicate 예시

조건을 검사하여 boolean 반환

Predicate<Integer> isPositive = x -> x > 0;
boolean result = isPositive.test(5);  // 결과: true

BiFunction 예시

두 인수를 받아 결과 생성

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
int result = add.apply(3, 4);  // 결과: 7

UnaryOperator 예시

입력과 동일한 타입으로 반환

UnaryOperator<String> toUpper = String::toUpperCase;
String result = toUpper.apply("hello");  // 결과: HELLO

BinaryOperator 예시

동일 타입 두 인수를 받아 같은 타입 반환

BinaryOperator<Integer> multiply = (a, b) ->  * ;
int result = multiply.apply(3, 4);  // 결과: 12

⚡ 12. 주요 특징 정리

  • @FunctionalInterface: 단 하나의 추상 메서드를 가진 인터페이스로, 어노테이션을 통해 컴파일러가 조건을 강제합니다.
  • 람다식 지원: 람다식 또는 메서드 참조로 간결하게 구현할 수 있어 코드 가독성이 향상됩니다.
  • Stream API 호환: filter(), map(), forEach() 등 스트림 작업에서 광범위하게 사용됩니다.
  • 기본 타입 특화 인터페이스: int, long, double에 특화된 인터페이스를 사용하면 오토박싱/언박싱 오버헤드를 제거하여 성능을 높일 수 있습니다.
  • 조합(Compose) 지원: Function.andThen(), Predicate.and() 등 디폴트 메서드를 통해 함수 합성이 가능합니다.

📝 13. 마무리

java.util.function 패키지의 함수형 인터페이스는 Java 함수형 프로그래밍의 핵심입니다. 처음에는 종류가 많아 헷갈릴 수 있지만, Consumer / Supplier / Function / Predicate 기본 4가지를 확실히 이해하면 나머지 파생 인터페이스도 자연스럽게 익힐 수 있습니다. Stream API와 함께 사용하면 코드를 훨씬 간결하고 읽기 쉽게 작성할 수 있으니 꼭 익혀두시길 권장합니다.

반응형