반응형
공급자
내부 코드
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Supplier는 매개변수를 받지 않고 단순히 반환하는 추상 메서드가 존재한다
활용 방식
1. 문자열 return
public class SupplierStringReturn {
public static void main(String[] args) {
Supplier<String> helloSupplier = () -> "Hi";
System.out.println(helloSupplier.get());
}
}
// 결과
// Hi
2. 객체 return
public class SupplierObjectReturn {
static class Point { }
public static void main(String[] args) {
Supplier<Point> pointSupplier = () -> new Point();
System.out.println(pointSupplier.get());
System.out.println(pointSupplier.getClass());
}
}
// 결과
// doodle.item03.SupplierObjectReturn$Point@4eec7777
// class doodle.item03.SupplierObjectReturn$$Lambda$1/1283928880
3. 메서드 참조 방식
public class SupplierMethodReference {
public static void main(String[] args) {
Supplier<String> supplier = SupplierMethodReference::getFire;
System.out.println(supplier.get());
}
private static String getFire() {
return "BOOM!";
}
}
// 결과
// BOOM!
4. 원시 타입 값 return
public class SupplierPrimitive {
public static void main(String[] args) {
BooleanSupplier booleanSupplier = () -> "a".equalsIgnoreCase("A");
DoubleSupplier doubleSupplier = () -> 5 / 3.0;
IntSupplier intSupplier = () -> 6 * 10;
LongSupplier longSupplier = () -> 5l + 10l;
System.out.println(booleanSupplier.getAsBoolean());
System.out.println(doubleSupplier.getAsDouble());
System.out.println(intSupplier.getAsInt());
System.out.println(longSupplier.getAsLong());
}
}
// 결과
// true
// 1.6666666666666667
// 60
// 15
5. 무한 Stream 생성
public class SupplierStreamGenerate {
public static void main(String[] args) {
Supplier<Double> supplier = () -> new Random().nextGaussian();
List<Double> list = Stream.generate(supplier)
.limit(6)
.collect(Collectors.toList());
System.out.println(list);
}
}
// 결과
// [0.4606804564124732, -1.13455907127883, -1.3330230626143407, 1.2478219314557397, -1.6212342383093146, -0.32124419611072896]
공급자를 활용하면 추상메서드 get()을 통해 Lazy Evaluation이 가능
Lazy Evaluation 정의
- 불필요한 연산을 피하기 위해 연산을 지연시키는 행위
- JPA에서의 지연 로딩과 유사한 뜻으로 생각됩니다
일반 상황
아래의 코드에서 printIfValidIndex
메서드가 호출되기 전에 getValue()
메서드가 호출되면서 스레드를 1초간 sleep 시키므로 결국 2초가 지연되게 됩니다.
public class LazyEvaluation {
public static void main(String[] args) {
long start = System.currentTimeMillis();
printIfValidIndex(10, getValue());
printIfValidIndex(-10, getValue());
System.out.println("It took " + ((System.currentTimeMillis() - start) / 1000) + " Second");
}
private static String getValue() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Valid";
}
private static void printIfValidIndex(int number, String value) {
if (number > 0) {
System.out.println(value);
} else {
System.out.println("Invalid");
}
}
}
// 결과
// Valid
// Invalid
// It took 2 Second
Supplier를 활용한 Lazy Evaluation
아래의 코드에서는 람다식인 () -> getValue()
가 호출되면 이를 Supplier로 받아서 사용합니다.
따라서 실제로 전달된 number가 0보다 큰 경우에 한해서 get()
메서드가 호출되면 getValue()
가 실제로 호출되어 1초간 지연이 됩니다.
public class LazyEvaluation2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
printIfValidIndex(10, () -> getValue());
printIfValidIndex(-10, () -> getValue());
System.out.println("It took " + ((System.currentTimeMillis() - start) / 1000) + " Second");
}
private static String getValue() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Valid";
}
private static void printIfValidIndex(int number, Supplier<String> valueSupplier) {
if (number > 0) {
System.out.println(valueSupplier.get());
} else {
System.out.println("Invalid");
}
}
}
// 결과
// Valid
// Invalid
// It took 1 Second
참고
아래 사이트에서 예제 코드 및 형식을 빌려와 직접 작성한 포스팅입니다.
반응형
'개발' 카테고리의 다른 글
[제네릭] Java에서 배열을 공변(covariant)으로 만든 이유는 무엇인가? (0) | 2022.02.14 |
---|---|
[제네릭] Unbounded Wildcard Type인 컬렉션에는 왜 null 값만 들어가는가? (0) | 2022.02.07 |
[5분 개념] 제네릭 싱글턴 팩터리 (0) | 2022.01.24 |
[Java] 예제 코드로 알아보는 다형성 - 2 (0) | 2022.01.24 |
[Java] 예제 코드로 알아보는 다형성 - 1 (0) | 2022.01.24 |