Supplier 인터페이스
도입 시기 | JAVA 8 |
분류 | 함수형 인터페이스 |
함수 원형 | @FunctionalInterface public interface Supplier<T> |
필드 | X |
메서드 | T get() |
특징 | T 타입을 반환하는 함수를 정의하고 get 메서드를 통해 결과를 리턴하는 메서드 하나만 가지고 있다. |
사용 예제
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 에 대해 더 자세히 알고 싶으면 아래 동영상 링크를 확인하자.