optional jihoon - GANGNAM-JAVA/JAVA-STUDY GitHub Wiki
API Note: Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.
'๊ฒฐ๊ณผ ์์(no result)'์ ๋ช ํํ ๋ํ๋ผ ํ์๊ฐ ์๊ณ , null์ ๋ฆฌํดํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ํฉ์์
๋ฉ์๋์ ๋ฆฌํด ํ์
์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด Optional์ ์ฒ์ ์๋๋ค. Optional ํ์ ์ ๋ณ์๋ ๊ฐ์ด ์ ๋ null ์ด์ด์๋ ์ ๋๋ฉฐ, ํญ์ Optional ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค.
- Optional ํด๋์ค๋ 'T'ํ์ ์ ๊ฐ์ฒด๋ฅผ ํฌ์ฅํด ์ฃผ๋ Wrapper class ์ด๋ค.
- ๋ฐ๋ผ์, Optional ์ธ์คํด์ค๋ ๋ชจ๋ ํ์ ์ ์ฐธ์กฐ ๋ณ์๋ฅผ ์ ์ฅํ ์ ์๋ค.
- Optional ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๊ณต๋๋ ๋ฉ์๋๋ก ์์์น ๋ชปํ NullPointerException ์์ธ๋ฅผ ํํผํ ์ ์๋ค. ์ฆ, ๋ณต์กํ ์กฐ๊ฑด๋ฌธ ์์ด๋ null ๊ฐ์ผ๋ก ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋๋ค.
-
of
- ๋ฉ์๋ ์๊ทธ๋์ฒ
static <T> Optional<T> of(T value)
- ๊ฐ์ด null์ผ ๊ฒฝ์ฐ NullPointerException ๋ฐ์
- ์ฆ, ์์๊ฐ์ด ๋ฐ๋์ ์์ด์ผ ํ๊ณ , ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํค๊ณ ์ถ์ ๋ ์ฌ์ฉ
- ์์
Optional<String> opt = Optional.of("test");
- ๋ฉ์๋ ์๊ทธ๋์ฒ
-
ofNullable
- ๋ฉ์๋ ์๊ทธ๋์ฒ
static <T> Optional<T> ofNullable(T value)
- ๊ฐ์ด null์ผ ์๋ ์์ ๋ ์ฌ์ฉ
- ๊ฐ์ด null์ผ ๊ฒฝ์ฐ ๋น์ด์๋ Optional ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๊ณ , ์ค๊ฐ ๋ฐ ์ข ๋จ ์ฒ๋ฆฌ ๋ฉ์๋ ์ฒด์ด๋์ ํตํด ์ํ๋ ๊ฐ ๋์ถ ๊ฐ๋ฅ
- ์ฒด์ด๋์ ํ๋๋ผ๋ ๊ฐ์ด null์ผ ๊ฒฝ์ฐ ์ค๊ฐ ์ฐ์ฐ์ ์ํ๋์ง ์์ผ๋ฉฐ ์ข ๋จ ์ฐ์ฐ๋ง ์ํ๋๋ค.
- ์์
Optional<String> opt = Optional.ofNullable("test");
- ๋ฉ์๋ ์๊ทธ๋์ฒ
-
empty
- ๋ฉ์๋ ์๊ทธ๋์ฒ
static <T> Optional<T> empty()
- ๋น์ด์๋ Optional ์ธ์คํด์ค๋ฅผ ์์๋ก ์์ฑํ๋ค.
- ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ถ๊ธฐ๋ฅผ ์ํํ๊ฑฐ๋, ๋ฆฌํด ๊ฐ์ด ์์ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
- ์์
Optional<String> opt = Optional.empty();
- ๋ฉ์๋ ์๊ทธ๋์ฒ
์์ฑ๋ Optional ์ธ์คํด์ค์ ๋ฉ์๋๋ฅผ ์ฐ๊ฒฐํ์ฌ ์ํ๋ ์ฐ์ฐ์ ์ํํ ์ ์๋ค.
๊ฐ ๋ฉ์๋๋ค์ ๋ค์ Optional ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๊ธฐ ๋๋ฌธ์ ์ฒด์ด๋ ์ฐ์ฐ์ ํตํด ๋ฐ๋ณต ์ฐ๊ฒฐ์ด ๊ฐ๋ฅํ๋ค.
-
filter
- ๋ฉ์๋ ์๊ทธ๋์ฒ
Optional<T> filter(Predicate<? super T> predicate)
- filter๋ ๊ฐ์ ๋ฐ์์ boolean ๊ฐ์ ๋ฆฌํดํ๋ Predicate ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
- ๊ทธ ๊ฒฐ๊ณผ๊ฐ true๋ฉด ๊ฐ์ด ์กด์ฌํ๋ Optional ์ธ์คํด์ค๋ฅผ, false๋ฉด ๋น Optional ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๋ค.
- ์์
Optional.ofNullable("111").filter(v -> "111".equals(v));
-
map
- ๋ฉ์๋ ์๊ทธ๋์ฒ
<U> Optional<U> map(Function<? super T,? extends U> mapper)
- ์ธ์์ ๋ฆฌํด๊ฐ์ ๋ชจ๋ ์ง์ ํ๋ Function ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
- ์๋ ์์์ Integer์ parseInt ํจ์๋ ์ด๋ฏธ ์ธ์์ ๋ฆฌํด๊ฐ์ด ๊ณ ์ ๋์ด ์๊ธฐ ๋๋ฌธ์, ํ์ ์ถ๋ก ์ ํตํด Function ์ธํฐํ์ด์ค์ ์ธ์์ ๋ฆฌํด ํ์ ์ด ์๋ ์ค์ ๋๋ค.
- map์ Optional๋ก ๊ฐ์ธ์ง ๊ฐ์ ๋ด๋ถ์ ๊ตฌํํ Function ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋ณํํด์ ๋ฆฌํดํ๋ ์ญํ ์ ํ๋ค.
- ์์
Optional.ofNullable("001").map(Integer::parseInt);
-
flatMap
- ๋ฉ์๋ ์๊ทธ๋์ฒ
<U> Optional<U> flatMap(Function<? super T,? extends Optional<? extends U>> mapper)
- map๊ณผ ๋น์ทํ์ง๋ง, Function ํจ์ํ ์ธํฐํ์ด์ค์ ๋ฆฌํด์ Optional๋ก ํด์ผ ํ๋ค.
- ์์
Optional.ofNullable("001").flatMap(v -> Optional.of(Integer.parseInt(v)));
-
or
- ๋ฉ์๋ ์๊ทธ๋์ฒ
Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
- ๊ฐ์ด ์กด์ฌํ๋ฉด ํด๋น ๊ฐ์ ๊ฐ์ธ๋ Optional ์ธ์คํด์ค๋ฅผ, ๊ทธ๋ ์ง ์์ผ๋ฉด suppier ํจ์ํ ์ธํฐํ์ด์ค๋ก ์์ฑ๋ Optional ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๋ค.
- ๋ฆฌํด ํ์ ์ด Optonal์ด๊ธฐ ๋๋ฌธ์ ๊ณ์ํด์ orElse์ ๊ฐ์ Optional ํด๋์ค์ ๋ฉ์๋๋ค์ ์ฐ์์ ์ผ๋ก ํธ์ถํ ์ ์๊ฒ ๋๋ค.
- ๊ธฐ์กด์ orElseGet๋ orElse๊ฐ ์ฃผ๋ก ๋ฉ์๋ ์ฑ์ธ(Chain)์ ์ต๋ง๋จ์์ ์ต์ข ์ ์ผ๋ก Optional ๊ฐ์ฒด๊ฐ ๋ด๊ณ ์๋ ๊ฐ์ ์ป๊ธฐ์ํด์ ์ฌ์ฉ๋๋ค๊ณ ํ๋ค๋ฉด, or์ ์ฃผ๋ก ๋ฉ์๋ ์ฑ์ธ์ ์ค๊ฐ์์ Optionl ๊ฐ์ฒด๊ฐ ๋น์ด์์ ๊ฒฝ์ฐ ๊ฐ์ ์ฑ์์ฃผ๊ธฐ ์ํ ์ฉ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์์
String coffeeToMake = Optional .ofNullable(order) .map(Order::getCoffee) .orElse("Americano"); System.out.println("๋ง๋ค ์ปคํผ : " + coffeeToMake);
Optional์ ๋๋ธ๋ค๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๋ญ๊ฐ ๋ฆฌํดํ๋ ์์ ์ด ์๋ค๋ฉด Optional ์ธ์คํด์ค๊ฐ ์๋, ๊ฐ ์์ฒด๋ฅผ ๋ฆฌํดํ๋ค.
-
ifPresent
- ๋ฉ์๋ ์๊ทธ๋์ฒ
void ifPresent(Consumer<? super T> action)
- Optional ๊ฐ์ด ์์ ๊ฒฝ์ฐ ์ํํ ๋ก์ง์ ์ ์ํ ์ ์๋ค.
- ์ ์๋๋ ์์ ์ Consumer ํจ์ํ ์ธํฐํ์ด์ค๋ก, ๋ฆฌํด ๊ฐ ์ด ์๋ ์์ ์๋น ๋ก์ง์ด์ด์ผ ํ๋ค.
- ๋ฆฌํด ๊ฐ์ด ์๋ ์์ ์ ํ๊ณ ์ถ๋ค๋ฉด map์ ํ์ฉํ๋ฉด ๋๋ค.
- ์์
Optional.ofNullable("111").ifPresent(v -> { // todo })
-
ifPresentOrElse
- ๋ฉ์๋ ์๊ทธ๋์ฒ
void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
- ifPresent์ ๋ฌ๋ฆฌ, ๊ฐ์ด ์กด์ฌํ์ง ์์ ๋์๋ ์ํํ ๋ก์ง์ ์ถ๊ฐํ ์ ์๋ค.
- ์์
Optional.ofNullable(order) .map(Order::getCoffee) .ifPresentOrElse( coffee -> System.out.println("๋ง๋ค ์ปคํผ: " + coffee), () -> System.out.println("๋ง๋ค ์ปคํผ: " + user.getFavoriteCoffee()) );
-
isPresent
- ๋ฉ์๋ ์๊ทธ๋์ฒ
bolean isPresent()
- Optional ์ธ์คํด์ค๊ฐ ๋น์ด์๋ค๋ฉด false๋ฅผ, ๊ทธ ๋ฐ๋๋ผ๋ฉด true๋ฅผ ๋ฆฌํดํ๋ค.
- ์์
if(Optional.ofNullable("111").isPresent()){ // todo }
-
get
- ๋ฉ์๋ ์๊ทธ๋์ฒ
- ์ค์ ๊ฐ์ ๋ฆฌํดํ๋ค. ๊ทธ ๊ฐ์ด null์ด๋ฉด null์ ๊ทธ๋๋ก ๋ฆฌํดํ๊ธฐ ๋๋ฌธ์ exception์ด ๋ฐ์ํ ์ ์๋ค.
- ์์
City city = Optional.ofNullable(city).get()
-
orElse
- ๋ฉ์๋ ์๊ทธ๋์ฒ
T orElse(T other)
- ๊ฐ์ด ์กด์ฌํ๋ฉด ์ค์ ๊ฐ์, ๊ทธ๋ ์ง ์์ผ๋ฉด other๋ฅผ ๋ฆฌํดํ๋ค. default ๊ฐ์ ์ค์ ํ ์ ์๋ค.
- ์์
return Optional.ofNullable(null).orElse("zzz");
-
orElseGet
- ๋ฉ์๋ ์๊ทธ๋์ฒ
T orElseGet(Supplier<? extends T> supplier)
- orElse์ ๋น์ทํ์ง๋ง, ์ธ์๊ฐ ๊ฐ์ฒด๊ฐ ์๋ Supplier ํจ์ํ ์ธํฐํ์ด์ค์ด๋ค. ์ฆ, ๊ฐ์ ๊ตฌํ๊ธฐ ์ํ ๋ณ๋ ๋ก์ง์ ์ถ๊ฐ๋ก ์ ์ํ ์ ์๋ค.
- ์์
return Optional.ofNullable(null).orElseGet(() -> { String returnStr = "default"; // todo return returnStr; });
-
orElseThrow
- ๋ฉ์๋ ์๊ทธ๋์ฒ
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X extends Throwable // Java8 T orElseThrow() // Java10
- Optional ๊ฐ์ฒด๊ฐ ๋น์ด์๋ค๋ฉด ์ฌ์ฉ์๊ฐ ์ ์ํ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
- ์ธ์๊ฐ ์๋ ๋ฉ์๋์ ๊ฒฝ์ฐ
- ์์
return Optional.ofNullable(null).orElseThrow(() -> { return new NullPoitnerException(); }); return Optional.ofNullable(null).orElseThrow();
-
stream
- ๋ฉ์๋ ์๊ทธ๋์ฒ
Stream<T> stream()
- ์ต์ ๋ ๊ฐ์ฒด๋ฅผ ์คํธ๋ฆผ ๊ฐ์ฒด๋ก ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์์
Stream<Optional<String>> optionalStream = Stream.of(Optional.of("Americano"), Optional.of("Latte"), Optional.empty(), Optional.of("Cappuccino")); List<String> validCoffeeList = optionalStream .flatMap(Optional::stream) .collect(Collectors.toList()); System.out.println("๋ง๋ค ์ปคํผ ๋ชฉ๋ก: " + validCoffeeList);
- ofNullable์ด ์๋๋ฐ, of๊ฐ ์กด์ฌํ๋ ์ด์
- of๋ฅผ ์ด๋ค๋ ๊ฒ์ ๊ฐ์ด null์ด ์๋๋ผ๋ ๊ฒ์ ํ์ ํ๋ค๋ ๊ฒ์ด๋ค. ์ด๋ฌํ ์ํฉ์์ ofNullable๋ฅผ ์ฌ์ฉํ์ฌ null์์๋ ์๋ฌ ์์ด ์กฐ์ฉํ ์๋ชป๋ ์ํ๋ก ๋์๊ฐ๊ฒ ๋๋ ๊ฒ์ด๋ค.
- map๊ณผ flatmap ์ฐจ์ด
public class Person {
private Optional<Car> optionalCar;
public Optional<Car> getOptionalCar() {
return optionalCar;
}
}
public class Car {
private Optional<Insurance> optionalInsurance;
public Optional<Insurance> getOptionalInsurance() {
return optionalInsurance;
}
}
public class Insurance {
private String name;
public String getName() {
return name;
}
}
public class Test {
// map cannot deal with nested Optionals
public Optional<String> getCarInsuranceName(Person person) {
return person.getOptionalCar()
.map(Car::getOptionalInsurance) // โ leads to a Optional<Optional<Insurance>
.map(Insurance::getName); // โก
}
}
public Optional<String> getCarInsuranceName(Person person) {
return person.getOptionalCar()
.flatMap(Car::getOptionalInsurance)
.map(Insurance::getName);
}
- https://docs.oracle.com/javase/9/docs/api/java/util/Optional.html
- http://homoefficio.github.io/2019/10/03/Java-Optional-%EB%B0%94%EB%A5%B4%EA%B2%8C-%EC%93%B0%EA%B8%B0/
- https://m.blog.naver.com/PostView.nhn?blogId=vefe&logNo=221727362911&proxyReferer=https:%2F%2Fwww.google.com%2F
-
https://www.daleseo.com/java9-optional/
- or
-
https://stackoverflow.com/a/31696584
- ofNullable์ด ์๋๋ฐ, of๊ฐ ์กด์ฌํ๋ ์ด์