본문 바로가기
Programming/Java

[Java] 자바 함수형 인터페이스(Functional Interface)

by hyunipad 2022. 6. 22.
반응형

2022.06.08 - [Programming/Java] - [Java] 자바 람다식(Lambda Expression)이란?

 

[Java] 자바 람다식(Lambda Expression)이란?

자바 8부터 추가된 스트림(Stream)을 사용하기 위해서는 람다식(Lambda Expression)의 이해가 필수적입니다. 이번 포스팅에서는 람다식에 대해 알아보도록 하겠습니다. 람다식(Lambda Expression) 이란? 람다

hyunipad.tistory.com

람다식은 함수형 인터페이스를 반환하게 되는데, 이 함수형 인터페이스는 자주 쓰는 패턴이 정해져 있습니다.

파라미터가 있거나 없거나, 리턴 값이 있거나 없거나 달라지는 것은 람다식을 통해 구현되는 구현부입니다.

 

자바에서는 빈번히 사용되는 함수형 인터페이스들을 java.util.function 패키지에 정의하여 제공하고 있습니다. 

 

아래는 java.util.function 패키지에서 제공되는 5가지의 함수형 인터페이스들의 계열입니다.

종류 파라미터 리턴 메서드
Consumer 계열 O X void accept(T)
Supplier 계열 X O T get()
Function 계열 O O T apply(R)
Operation 계열 O O T xxx(R)
Predicate 계열 O boolean boolean test(T)

 

 

Consumer 계열

Consumer<String> consumer = str -> System.out.println(str); // str 이라는 파라미터를 받아서 출력
consumer.accept("hello!!");

Consumer 계열은 파라미터를 받아서 소비한다고 하여 Consumer라는 이름이 붙었습니다. 리턴은 하지 않습니다.

 

아래는 Consumer 계열 함수형 인터페이스의 종류입니다,

인터페이스명 메서드 설명
Consumer<T> void accept(T t) T 타입 객체를 파라미터로 받음
BiConsumer<T, U> void accept(T t, U u) T 타입 객체와 U타입 객체를 파라미터로 받음
PConsumer void accept(p value) p 타입의 값을 파마리터로 받음
ObjPConsumer<T> void accept(T t, p value) T 타입 객체외 p 타입의 값을 파라미터로 받음

Consumer<T>는 객체 하나를 파라미터로 받아서 처리합니다.

 

BiConsumer<T, U>는 객체 두 개를 파라미터로 받아서 처리합니다. 

 

객체를 파라미터로 받지 않고 기본형을 파라미터로 받는 경우 double, int, long 값을 처리할 수 있습니다. 이때 인터페이스명은 각각 DoubleConsumer, IntConsumer, LongConsumer 입니다.

 

객체와 기본형을 같이 파라미터로 받는 경우에는 위의 인터페이스명에 Obj를 접두사로 추가해줍니다. 따라서 인터페이스명은 각각 ObjDoubleConsumer, ObjIntConsumer, ObjLongConsumer 입니다.

 

참고로 int는 객체형으로 Integer가 존재하여 객체 타입으로써 Consumer<Integer>를 사용할 수 있지만, 내부적으로는 오토 박싱이 일어나기 때문에 성능상으로 좋지 않기 때문에 IntConsumer를 사용하는 것이 좋습니다.

 

 

Supplier 계열

Supplier<String> supplier = () -> { return "hello"; }; // 파라미터를 받지 않고 hello를 리턴
System.out.println(supplier.get());

IntSupplier supplier2 = () -> { // 파라미터를 받지 않고 난수를 생성하여 리턴
    Random random = new Random();
    return random.nextInt(10); 
};
System.out.println(supplier2.getAsInt());

Supplier는 리턴 값을 공급해준다 하여 Supplier라는 이름이 붙었습니다. Supplier는 파라미터를 받지 않고 자체적으로 값을 만들어 리턴해줍니다.

 

아래는 Supplier 계열의 함수형 인터페이스의 종류입니다.

인터페이스명 메서드 설명
Supplier<T> T get() T타입의 객체를 리턴합니다.
PSupplier p getAsP() p 타입의 값을 리턴합니다.

Supplier 계열도 Consumer 계열과 마찬가지로 기본형을 리턴해주는 경우 인터페이스명은 각각 DoubleConsumer, IntConsumer, LongConsumer입니다.

 

 

Function 계열

Function<String, Integer> function = (str) -> { return str.length(); }; // 파라미터로 받은 문자열의 길이를 리턴
System.out.println(function.apply("hello"));

ToIntBiFunction<String, String> function2 = (str1, str2) -> { // 파라미터로 받은 문자열의 길이의 합을 리턴
    return str1.length() + str2.length(); 
}; 
System.out.println(function2.applyAsInt("hello", "function"));

Function 계열은 Consumer 계열과 Supplier 계열을 합친 함수형 인터페이스입니다. 파라미터를 받은 다음 메서드 내부에서 값을 처리한 다음 리턴합니다.

 

Function 계열은 다양한 함수형 인터페이스가 제공되지만, 위의 두 개의 계열과 크게 다르지 않습니다.

아래는 Function 계열 함수형 인터페이스의 종류입니다.

인터페이스명 메서드 설명
Function<T, R> R apply(T t) T 타입 파라미터를 받고 R 타입을 리턴
BiFunction<T, U, R> R apply(T t, U u) T, U 타입 파라미터를 받고 R 타입을 리턴
PFunction<R> R apply(p value) p 타입 값을 받고 R 타입을 리턴
PtoQFunction q applyQsQ(p value) p 타입 값을 받고 q 타입을 리턴
ToPFunction<T> p applyAsP(T t) T 타입 파라미터를 받고 p 타입을 리턴
ToPBiFunction<T, U> p appluAsP(T t, U u) T, U 타입 파라미터를 받고 p 타입을 리턴

 

 

Operator 계열

UnaryOperator<Double> operator = (x) -> { return Math.pow(x, 2); };
System.out.println(operator.apply(10.0));

DoubleBinaryOperator operator2 = (x, y) -> { return Math.max(x, y); };
System.out.println(operator2.applyAsDouble(100, 200));

Operator 계열은 Function 계열과 똑같습니다. 다만 Function 계열은 파라미터와 리턴 타입이 무관하지만, Operator 계열은 파라미터와 같은 타입이 리턴됩니다.

 

아래는 Operator 계열 함수형 인터페이스 종류입니다.

인터페이스명 메서드 설명
UnaryOperator<T> T apply(T t) T 타입 파라미터를 받고 T 타입을 리턴
BinaryOperator<T> T apply(T t1, T t2) T, T 타입 파라미터를 받고 T 타입을 리턴
PUnaryOperator P applyAsp(p value) p 타입 값을 받고 p 타입을 리턴
PBinaryOperator P applyAsp(p value1, p value2) p, p 타입 값을 받고 p 타입을 리턴

 

 

Predicate 계열

Predicate<String> predicate = (name) -> { return name.contains("java"); };
System.out.println(predicate.test("java Action"));

DoublePredicate predicate2 = (num) -> { return num > 0.5; };
System.out.println(predicate2.test(1.3));

Predicate는 파라미터도 받고 리턴도 있지만, 다른 점은 리턴 값이 boolean타입으로 고정되어 있다는 것입니다.

 

아래는 Predicate 계열 함수형 인터페이스 종류입니다.

인터페이스명 메서드 설명
Predicate<T> boolean test(T t) T 타입 파라미터를 받고 boolean 타입을 리턴
BiPredicate<T> boolean test(T t, U u) T, U 타입 파라미터를 받고 boolean  타입을 리턴
PPredicate boolean test(P value) P 타입 값을 받고 boolean  타입을 리턴

 

반응형

댓글