- Optional은 반환값이 없을 수 있으며 클라이언트가 이를 대비해야 할 때 사용하라
- 컬렉션을 Optional로 감싸기보다 빈 컬렉션을 반환하라
- 꽤 비싼 객체이다
- 옵셔녈을 컬렉션의 키, 값, 원소나 배열의 원소로 사용하지 마라
자바 8이전 값을 반환할 수 없을 때, 2가지 선택지
- 예외 반환 => 문제 : stack 캡처 고비용 / 진짜 예외 상황이 아닐 수 있음
- null 반환 => 문제 : 클라에서 null 처리 필요 => 반환값이 없을 수도 있음을 API 사용자에게 알려주는 효율적 기능이 필요!
- 결과가 없을 수 있음
- 클라이언트가 이 상황을 특별히 처리해야 함
ex) 컬렉션에 원소가 없을 때
before :예외 반환
public static <E extends Comparable<E>> E max1(Collection<E> c) {
if (c.isEmpty())
throw new IllegalArgumentException("Empty collection");
...
}
after : Optional empty 반환
public static <E extends Comparable<E>>
Optional<E> max2(Collection<E> c) {
if (c.isEmpty())
return Optional.empty();
...
}
- Optional을 도입한 취지를 무시하는 행위다
- 컨테이너 타입 : 컬렉션, 스트림, 배열, 옵셔널
- Optional<List>가 아닌 빈 List를 반환하라
- 한번 래핑하는 과정의 비용이 있을 수 밖에 없다
- 박싱된 기본 타입을 담은 옵셔녈 반환을 지양하라(Integer, Long, Double)
- 미리 준비되어 있다 => OptionalInt, OptionalLong, OptionalDouble
- 혼란과 오류 가능성을 높인다
- ex) 맵의 value로 Optional을 사용 > 키가 없음을 나타내는 맥락이 2개가 됨(키가 없을 때, 옵셔녈 반환할 때)
- orElse : 기본 값 반환
String lastWordLexicon = max(words).orElse("단어 없음...");
- orElseThrow(Supplier<? extends Exception> exceptionSupplier) : 없으면 예외 반환
Toy myToy = max(toys).orElseThrow(IllegalArgumentException::new);
- orElseGet(Supplier<? extends T> other) : emtpy이면 => Supplier를 통한 값 반환
- ifPresent(Consumer<? super T) consumer) : 값이 존재할 때 인수로 넘겨준 동작 실행
- ifPresentOrElse(Consumer<? super T> consumer, Runnable, emptyAction) : Optional이 비었을 때 실행가능한 Runnable
- Optional은 stream 연산이 가능하다
- 여러 연산이 있지만 그 중 map 연산만 잘 이해하고 넘어가자
- map은 마치 다음과 같은 의미로 사용된다 : 있으면 수행하라
- 없으면 아무 일도 일어나지 않는다
Optional<People> people = Optional.ofNullable(null);
if(people.isPresent()) {
name = people.get().getName();
}
Optional<People> people = Optional.ofNullable(null);
Optional<String> name = people.map(People::getName);;