du.study기록공간

Java @FunctionalInterface - Function 본문

자바

Java @FunctionalInterface - Function

du.study 2021. 12. 14. 00:40
728x90

이번에는 @FunctionalInterface 하나인 Function에 대해 기록하고자 합니다.

Function을 간략하게 설명한다면 객체(T)를 받아 객체(R)을 리턴하는 함수형 인터페이스 입니다. 

코드를 보면 아래와같은 기능을 가지고 있습니다.

public interface Function<T, R> {
    R apply(T t);
    
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

 

1. apply 

먼저 apply를 살펴보면 다음과 같은 예제를 들 수 있습니다.

Function<Integer, Integer> fun1 =  x -> x * x;
Function<Integer, String> fun2 = Object::toString;
Function<String, Object> fun3 = x -> {
     if(x == null){
        return "";
     }
     return x;
};

System.out.println(fun1.apply(2)); // 4
System.out.println(fun2.apply(2)); // 2
System.out.println(fun3.apply("test")); // "test"
System.out.println(fun3.apply(null)); // ""

정말 간단하게 앞에있는 타입을 받아 뒤에있는 타입으로 리턴하는 예제를 볼 수 있습니다.

 

2. compose

compose의 경우 리턴으로 Function을 반환하기에 Function간의 체이닝이 가능합니다.

변수로 전달된 함수를 먼저 실행한 후, 호출하는 함수가 실행되는 구조입니다.

Function<Integer, Integer> multi = x -> x * 5;
Function<Integer, Integer> add = x -> x + 5;

Function<Integer, Integer> addThenMultiply = multi.compose(add);
System.out.println(addThenMultiply.apply(2)); // 35

 

3. andThen

andThen또한 동일하게 Function을 반환하기에 체이닝이 가능하지만, 앞의 compose()와는 반대로 동작합니다.

andThen을 호출하는 함수를 먼저 실행한 후, 변수로 전달된 함수를 실행하게 됩니다.

아래의 경우 곱샘 후 +연산을 하는 코드가 됩니다.

Function<Integer, Integer> multi = x -> x * 5;
Function<Integer, Integer> add = x -> x + 5;

Function<Integer, Integer> multiplyThenAdd = multi.andThen(add);
System.out.println(multiplyThenAdd.apply(2)); // 15

 

 

4. identity 

identity의 경우 동일한 값을 리턴하는 static method입니다. 람다식 표현을 대신해주는 부분도 있고  foreach나 단순값을 반환해야할때 주로 사용할 것 같습니다.

    Function<String, String> fun1 = Function.identity();
    Function<String, String> fun2 = x -> x; // lambda expression
    
    System.out.println(fun1.apply("Test")); // "Test" 
    System.out.println(fun2.apply("Test")); // "Test"

.. 음 실제로 이부분을 프로젝트에선 코드에 사용하고있지않아 어떻게 쓰일까 하는 궁금증이 있네요

728x90
Comments