Optional은 null이 올 수 있는 값을 감싸는 Wrapper 클래스로 선택형값을 캡슐호하는 클래스다.
NullPointerException
은 자바에서 가장 흔히 발생하는 에러다정적 팩토리 메서드 Optional.empty
로 빈 Optional 객체를 얻을 수 있다.
Optional<String> optStr = Optional.empty();
정적 팩토리 메서드 Optional.of
로 null이 아닌 값을 포함하는 Optional을 만들 수 있다.
Optional<String> optStr = Optional.of("test");
안에 null을 참조하게 되면 그 즉시 NullPointerException
가 발생하게 된다.
정적 팩토리 메서드 Optional.ofNullable
로 null값을 저장할 수 있는 Optional을 만들 수 있다.
Optional<String> optStr = Optional.ofNullable("test");
값을 추출하고 변환하는 기능을 위해 Optional은 map
을 지원한다.
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName);
Optional 값이 있다면 map 인수로 제공된 함수가 값을 변경하고 비어있으면 아무 일도 일어나지 않는다.
map을 통해 파이프라인을 형성한다면 문제가 발생한다.
Optional<Person> optPerson = Optional.of(person);
Optional<String> name =
optPerson.map(Person::getCar)
.map(Car::getInsurance)
.map(Insurance::getName);
map은 Optional의 형식을 반환한다. 여러번의 map을 사용한다면 아래와 같이 중첩된 Optional 구조를 반환하게 된다.
따라서 다음과 같이 사용해야한다.
Optional<Person> optPerson = Optional.of(person);
Optional<String> name =
optPerson.flapMap(Person::getCar)
.flapMap(Car::getInsurance)
.flapMap(Insurance::getName);
자바 9에서는 Optional을 포함하는 스트림을 쉽게 처리할 수 있도록 Optional에 stream()
을 추가했다.
Optional 스트림을 값을 가진 스트림으로 변환할 때 유용하다.
Stream<Optional<String>> stream = ...;
Set<String> result = stream.filter(Optional::isPresent)
.map(Optional::get)
.collect(toSet());
Optional 클래스는 인스턴스에 포함된 값을 읽는 다양한 방법을 제공한다.
get()
NoSuchElementException
을 발생시킨다.orElse(T other)
orElseGet(Supplier\<? extends T> other)
orElseThrow(Supplier\<? extends X> exceptionSupplier)
ifPresent(Consumer\<? super T> consumer)
ifPresentOrElse(Consumer\<? super T> action, Runnable emptyAction)
특정 조건에 부합하는 값을 얻고 싶을 때 사용한다.
Optional<Insurance> optInsurance = ...
optInsurance.filter(insurance -> "test".equals(insurance.getName()))
.ifPresent(x -> System.out.println("ok"));
조건과 일치하면 값을 반환하고 아니면 빈 Optional 객체를 반환한다.
메서드 | 설명 |
---|---|
empty | 빈 Optional 인스턴스 반환 |
filter | 값이 존재하며 조건과 일치하면 값을 포함하는 Optional을 반환, 값이 없거나 조건과 불일치시 빈 Optional 반환 |
flatMap | 값이 존재하면 인수로 제공된 함수 결과 Optional을 반환, 값이 없으면 빈 Optional 반환 |
get | 값이 존재하면 Optional이 감싸고 있는 값을 반환, 값이 없으면 NoSuchElementException 발생 |
ifPresent | 값이 존재하면 지정된 Consumer 실행, 없으면 아무 일도 일어나지 않음 |
ifPresentOrElse | 값이 존재하면 지정된 Consumer 실행, 없으면 아무 일도 일어나지 않음 |
isPresent | 값이 존재하면 true 반환, 없으면 false 반환 |
map | 값이 존재하면 제공된 매핑 함수 적용 |
of | 값이 존재하면 값을 감싸는 Optional 반환, null이면 NullPointerException 발생 |
ofNullable | 값이 존재하면 값을 감싸는 Optional 반환, 값이 null이면 빈 Optional 반환 |
or | 값이 존재하면 같은 Optional 반환, 값이 없으면 Supplier에서 만든 Optional 반환 |
orElse | 값이 존재하면 값을 반환, 값이 없으면 기본값을 반환 |
orElseGet | 값이 존재하면 값을 반환, 값이 없으면 Supplier에서 제공하는 값 반환 |
orElseThrow | 값이 존재하면 값을 반환, 값이 없으면 Supplier에서 생성한 예외 발생 |
stream | 값이 존재하면 존재하는 값만 포함하는 스트림 반환, 없으면 빈 스트림 반환 |
Reference