728x90
반응형
SMALL

Optional 값 획득

isPresent(), isEmpty()

  • 값이 있으면(없으면) true, 없으면(있으면) false.

get()

  • 값이 있는 경우 그 값을 반환
  • 값이 없으면 NoSuchElementException 발생
  • 직접 사용 시 주의해야 하며, 가급적이면 orElse, orElseXxx 계열 메서드를 사용하는 것이 안전

orElse(T other)

  • 값이 있으면 그 값을 반환
  • 값이 없으면 other를 반환
  • 즉시 평가 (즉, other에 대한 연산을 바로 수행)

orElseGet(Supplier<? extends T> supplier)

  • 값이 있으면 그 값을 반환
  • 값이 없으면 supplier 호출하여 생성된 값 반환
  • 지연 평가 (필요한 시점에만 supplier.get()가 실행)

orElseThrow(...)

  • 값이 있으면 그 값을 반환
  • 값이 없으면 지정한 예외를 던짐

or(Supplier<? extends Optional<? extends T>> supplier)

  • 값이 있으면 해당 값의 Optional을 그대로 반환
  • 값이 없으면 supplier가 제공하는 다른 Optional을 반환
  • 값 대신 Optional을 반환한다는 특징

 

Optional 값 처리

ifPresent(Consumer<? super T> action)

  • 값이 존재하면 action 실행
  • 값이 없으면 아무것도 안 함

ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

  • 값이 존재하면 action 실행
  • 값이 없으면 emptyAction 실행

map(Function<? super T, ? extends U> mapper)

  • 값이 있으면 mapper를 적용한 결과 (Optional<U>) 반환
  • 값이 없으면 Optional.empty() 반환

flatMap(Function<? super T, ? extends Optional<? extends U>> mapper)

  • map과 유사하지만, Optional을 반환할 때 중첩되지 않고 평탄화(flat)해서 반환

filter(Predicate<? super T> predicate)

  • 값이 있고 조건을 만족하면 그대로 반환
  • 조건 불만족이거나 비어있으면 Optional.empty() 반환

stream()

  • 값이 있으면 단일 요소를 담은 Stream<T> 반환
  • 값이 없으면 빈 스트림 반환

 

내가 Optional을 사용할 때 map, filter를 쓸 일이 있나? 라는 생각을 했는데 정말 어리석은 생각이었다. 어떤 메서드의 반환 타입이 Optional<T>라면, 이거 정말 깔끔하게 한줄로도 표현이 가능할 수 있다.

 

예제1

private Optional<String> getUserStreet(User user) {
    return Optional.ofNullable(user)
            .map(User::getAddress)
            .map(Address::getStreet);
}

 

예제2

private String getDeliveryStatus(Long orderId) {
    return findOrder(orderId)
            .map(Order::getDelivery)
            .filter(Predicate.not(Delivery::isCanceled))
            .map(Delivery::getStatus)
            .orElse("배송X");
}

private Optional<Order> findOrder(Long orderId) {
    return Optional.ofNullable(orderRepository.get(orderId));
}
  • Optionalmap, filter에서 값이 없으면 그냥 Optional.empty()로 되기 때문에 메서드 체인으로 정말 깔끔하게 처리가 가능했다.
  • 역시 사람은.. 겸손해야 하고 계속해서 배워야 한다. 
  • 이걸 배우기 전에는 아마 이렇게 작성했을 것이다.
private String getDeliveryStatus(Long orderId) {
    Order order = findOrder(orderId).orElseThrow();

    if (order.getDelivery() != null) {
        ...
    }
}

 

728x90
반응형
LIST

+ Recent posts