Java 8이 나온지도 5년 정도가 되어간다. 내가 군대에 있을 때 처음 릴리즈 된걸로 기억하는데, 굉장히 파격적인 변화를 가져온 버전이 나왔음에도 불구하고 여전히 활용을 제대로 하지 못하는 것 같아 제대로 공부할 겸 이렇게 포스팅을 하게 됐다.
이번 포스팅에서 주로 다루게 될 function API는 함수적 인터페이스, 람다식이라는 키워드에 대해 알아야 하는데 혹시나 아직 Java에서 람다식을 어떻게 쓰는건지 모르시는 분이 계시다면 이전 포스팅을 참고하면 되겠다.
[Programming/JAVA] - [JAVA] 람다식(Lambda Expression)이란?
[Programming/JAVA] - [JAVA] 다양한 형태의 람다식(예제)
이제 본격적으로 파헤쳐볼텐데, java.util.function 패키지를 앞으로는 줄여서 function 패키지라고 하겠다. function 패키지에는 크게 Consumer, Supplier, Function, Operator, Predicate가 있고, 각 기능들은 인터페이스에 선언된 추상 메소드의 파라미터와 리턴값의 유무를 기준으로 구분된다.
이번 포스팅에서는 가장 간단한 형태인 Consumer와 Supplier에 대해서만 다루고, 나머지는 다음 포스팅에서 다루도록 하겠다.
Consumer - 파라미터는 있고, 리턴 값은 없음
프로그래밍을 하다보면 네이밍이 굉장히 어려울 때가 많은데, 그런 의미에서 이 function 패키지의 네이밍은 경이롭다.
Consumer 인터페이스는 말 그대로 소비(?)만 하고 생산을 하지 않는다. 즉 파라미터로 입력은 받지만 리턴값은 없다.
Consumer에는 accept()라는 메소드가 있는데, 말했다시피 파라미터만 존재하고 리턴 값이 없는 메소드다.
Consumer에는 또 여러 종류가 있는데,
하나의 제네릭 매개변수를 받아 사용하는 Consumer<T>
두 개의 제네릭 매개변수를 받아 사용하는 BiConsumer<T, U>
Number 타입의 컨슈머들인 IntConsumer, DoubleConsumer, LongConsumer
Object와 Number들을 함께 사용하는 ObjIntConsumer, ObjDoubleConsumer, ObjLongConsumer
이해를 돕기 위해 예제를 간단하게 작성해보자면,
import java.util.function.*;
public class Example {
public static void main(String[] args) {
Consumer<String> consumer = o -> System.out.println(o);
consumer.accept("I'm ReadyKim");
IntConsumer intConsumer = n -> {
System.out.println("I'm ReadyKim");
System.out.println(n + " years old.");
};
inConsumer.accept(10);
}
}
보시다시피 람다식을 사용하여 리턴 값이 없는 실행문들을 Consumer에 대입했다가 필요할 때 accept 메소드를 통해서 실행할 수 있다. 지금 이렇게 간단한 예제만 살펴봤을 때는 메소드로 빼면 될 것이지 굳이 왜 저렇게 해야하나.. 싶을 수 있지만 인터페이스를 들고다닐 수 있다는 것은 객체 지향 소프트웨어 디자인 측면으로 봤을 때는 굉장히 유용한 기능이라 할 수 있다.
Supplier - 파라미터는 없고, 리턴 값은 있음
자, 이제 Consumer에 대해 알았으니 Supplier는 이해하기 쉽다. Supplier는 말 그대로 소비 없이 공급만 한다. 그렇기 때문에 파라미터는 없고, 리턴 값만 있다. Consumer가 메소드로 accpet()를 사용했다면 Supplier는 어쩐지 우리에게 익숙한 get() 메소드를 사용하면 된다.
Supplier도 종류가 나뉘긴 하지만 1개 이상의 매개변수가 들어갈 수 있는 Consumer와 달리 리턴 값은 오직 1개이기 때문에 상대적으로 종류가 적다.
제네릭 객체를 리턴하는 Supplier<T>
Boolean 값을 리턴하는 BooleanSupplier
Number 타입을 리턴하는 IntSupplier, DoubleSupplier, LongSupplier
이것도 마찬가지로 예제를 통해 명확하게 이해할 수 있을 것이다.
import java.util.function.*;
public class Example {
public static void main(String[] args) {
Supplier<String> supplier = () -> "ReadyKim";
String name = supplier.get();
System.out.println(name);
IntSupplier intSupplier = () -> {
int num = 100 * 100;
return num;
};
int result = intSupplier.getAsInt();
System.out.println(result);
}
}
* 참고로 기본이 되는 Supplier는 사용할 때 메소드가 get()이지만, 지정된 타입을 리턴하는 Boolean, Int, Double 등은 getAsBoolean()처럼 getAsXXX() 꼴로 사용해야 한다.
이상 Java 8부터 도입된 function API 중 Consumer와 Supplier에 대해 알아봤다. 새로 나온 API이기 때문에 낯설 수는 있지만 막상 공부를 해보니 어려운 개념은 아니다라는 생각이 들고, 잘 활용한다면 정말 유용하게 사용할 수 있을 기능이라는 생각이 든다. 다음 포스팅에서는 이번에 다루지 못한 더 다양한 function API에 대해 다뤄보도록 하겠다.
'JAVA' 카테고리의 다른 글
Java Atomic Type 이해하기(AtomicBoolean, AtomicInteger) (3) | 2019.08.29 |
---|---|
자바 스트림(Stream) 이해하기 (feat.JAVA 8) (0) | 2019.08.06 |
Java 가비지 컬렉터(GC) 이해하기 (1) | 2019.07.24 |
[JAVA] 다양한 형태의 람다식(예제) (0) | 2019.01.30 |
[JAVA] 람다식(Lambda Expression)이란? (0) | 2019.01.30 |