반응형

Supplier 인터페이스

 

도입 시기 JAVA 8
분류 함수형 인터페이스
함수 원형 @FunctionalInterface
public interface Supplier<T>
필드 X
메서드 T get()
특징 T 타입을 반환하는 함수를 정의하고 get 메서드를 통해 결과를 리턴하는 메서드 하나만 가지고 있다.

 

Intellij 에서 정의부분 캡처

 

사용 예제

public class Test {
    private int id;
    private String value;
    public Test(int id, String value) {
        this.id = id;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public String getValue() {
        return value;
    }
}

public class Example {

    public static void main(String[] args) {

        Supplier<Test> testSupplier = ()-> new Test(0, "Hello");
        Test result = testSupplier.get();
        System.out.println(result.getId() + ", " + result.getValue());
    }
}

 

Why? 어디에 쓰이는가?

함수형 인터페이스를 왜 사용하는 것인가에 대한 질문과 동일하다.

함수형 인터페이스는 1개의 추상 메서드를 가지고 있는 인터페이스를 의미한다. 자바의 람다 표현식이 이 함수 인터페이스로만 사용 가능하다. (람다 함수는 익명 함수로 함수를 간단하게 만드는 표현식이다.)

 

함수를 변수화할 수 있다는 의미이다. 변수로 다룰 경우 직접 계산하지 않아도 된다는 장점이 있다. (Lazy Evaluation)

 

다음과 같이 여러 변수를 체크하는 함수가 있는데 "func(T a, T b, T c)", c 라는 변수가 고비용이 발생하는 함수를 거쳐 반환이 된다고 가정하자. func 함수에서는 a 와 b 를 체크해서 c 라는 값을 계산할지 결정한다고 하면 c 라는 변수를 실제로 사용하지 않는 경우의 수도 있을 것이다. 보통 순차적으로 실행되기 때문에 c 라는 고비용 함수를 매번 거쳐야 되서 성능 이슈에 문제가 있을 수도 있다. 아래 예제를 살펴보자.

 

public class NumberWorld {
    private static void negativeTest(int number, String expression) {
        if (number < 0) {
            System.out.println("This Value is Negative Written by" + expression);
        } else {
            System.out.println("This Value is Positive");
        }

    }
    private static String expressionProcessing() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "gold-egg";
    }
    public static void main(String[] args) {
        negativeTest(-1, expressionProcessing());
        negativeTest(1, expressionProcessing());
        negativeTest(2, expressionProcessing());
    }
}

 

위 예제 negativeTest 함수는 number 가 양수일 때 고비용 함수 expressionProcessing 의 결과 값인 expression 을 사용하지 않아도 된다. 그럼에도 불구하고 매번 expressionProcessing 함수가 호출되는 것을 볼 수 있다. 실제 필요한 구간에만 실행하게 해준다면 더 빠른 속도로 처리할 수 있을 것이다. 이런 개념을 Lazy Evaluation 라고 한다.

 

Supplier 를 활용하여 Lazy Evaluation 을 적용하면 다음과 같이 작성할 수 있다.

 

public class NumberWorld {
    private static void negativeTest(int number, Supplier<String> expressionSupplier) {
        if (number < 0) {
            System.out.println("This Value is Negative Written by" + expressionSupplier.get());
        } else {
            System.out.println("This Value is Positive");
        }

    }
    private static String expressionProcessing() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "gold-egg";
    }
    public static void main(String[] args) {
        negativeTest(-1, () -> expressionProcessing());
        negativeTest(1, () -> expressionProcessing());
        negativeTest(2, () -> expressionProcessing());
    }
}

 

Supplier와 Lazy Evaluation 에 대해 더 자세히 알고 싶으면 아래 동영상 링크를 확인하자.

반응형

+ Recent posts