Optional
Optional<T>은 지네릭 클래스로 'T타입의 객체'를 감싸는 래퍼 클래스이다.
때문에 Optional 타입의 객체에는 모든 타입의 참조 변수를 담을 수 있다.
여기서 중요한것은 변수가 Optinal이라는 객체에 담아서 반환된다는 것이다.
이처럼 객체에 담아서 반환을 하면, 반환된 결과가 null인지 매번 if문으로 체크하는 대신 Optional에 정의된 메서드를 통해서 간단히 처리할 수 있다.
■ Optional 객체 생성
Optional 객체를 생성할 때는 of() 또는 ofNullable()을 사용한다.
[Optional 객체 생성 예]
Optional<String> optVal = Optional.of("abc");
Optional<String> optVal = Optional.of(new String("abc"));
Optional<String> optVal = Optioanl.of(null) // NullPointException 발생
Optional<String> optVal = Optional.ofNullable(null);
만일 참조변수의 값이 null일 가능성이 있으면, of() 대신 ofNullable()을 사용해야 한다.
Optional<T> 타입의 참조 변수를 기본값으로 초기화할 때는 empty()를 사용한다.
[empty() 사용 예]
Optional<String> optVal = Optional.<String>empty();
■ Optional 객체의 값 가져오기
Optional 객체에 저장된 값을 가져올 때는 get()을 사용한다.
get()으로 가져올 값이 null일 때는 NoSuchElementException이 발생하며, 이를 대비해서 orElse()로 대체할 값을 지정할 수 있다.
[get() & orElse()]
Optional<String> optVal = Optional.of("abc");
String str1 = optVal.get();
String str2 = optVal.orElse("");
orElse()는 Optional안의 값이 null일 경우 null 대신 매개변수로 받은 값을 대체해서 반환해준다.
위의 예제에서는 optVal의 값이 null 일 경우 빈 문자열("")을 반환한다.
orElse()의 변형으로는 null을 대체할 값을 반환하는 람다식을 지정할 수 있는 orElseGet()과 null일 때 지정된 예외를 발생시키는 orElseThrow()가 있다.
[orElseGet() & orElseThrow]
// T orElseGet(Supplier<? extends T> other)
String str = optVal.orElseGet(String::new);
// T orElseThrow(Supplier<? extends X> exceptionSupplier)
String str = optVal.orElseThrow(NullPointException::new);
Stream처럼 Optional 객체에도 filter(), map, flatMap()등 을 사용할 수 있다.
[Optional 사용 예_filter(), map()]
int result = Optional.of("123")
.filter(x->x.length() > 0)
.map(Integer::parseInt).orElse(-1);
위 예제는 Optional안의 값의 길이가 0보다 클 경우 parseInt()를 적용시키는 예제이다.
만약 Optional안의 값이 null이면 위 메서드들은 아무 일도 하지 않고, -1을 반환한다.
isPresent()는 Optional 객체의 값이 null이면 false를, 아니면 true를 반환한다.
ifPresent(Consumer<T> block)는 값이 있으면 주어진 람다식을 실행하고, 없으면 아무 일도 하지 않는다.
[ifPresent() 예]
Optional.ofNullable("abc").ifPresent(System.out::println);
위 예는 Optional안의 값이 있을경우 그 값을 출력하고, null이면 아무 일도 일어나지 않는다.
■ OptionalInt, OptionalLong, OptionalDouble
IntStream과 같은 기본형 스트림에는 Optional대신 기본형을 값으로 하는 OptionalInt, OptionalLong, OptionalDouble을 반환한다.
[OptionalInt를 반환하는 IntStream 메서드]
OptionalInt findAny()
OptionalInt findFirst()
OptionalInt reduce(IntBinaryOperator op)
OptionalInt max()
OptionalInt min()
OptionalDouble average()
반환 타입이 Optional<T>가 아니라는 것을 제외하고는 Stream에 정의된 것과 비슷하다.
또한 기본형 Optional에 저장된 값을 꺼낼 때 사용하는 메서드의 이름이 기존의 Optional과 조금씩 다르다.
[기본형 Optional 객체의 값을 가져오는 메서드]
기본형 int의 기본값은 0이므로 아무런 값도 갖지 않는 OptionalInt에 저장되는 값은 0이다.
그러나 OptionalInt.of(0)와 OptionalInt.empty()는 같지 않다.
OptionalInt 내의 isPresent라는 인스턴스는 값이 아예 없을 때 false를 반환하기 때문이다.
그러나 Optional 객체의 경우 null을 저장하면 비어있는것과 동일하게 취급한다.
'JAVA > 기본' 카테고리의 다른 글
자료구조 초기화, List-Array 변환 (0) | 2022.07.15 |
---|---|
스트림(Stream) (0) | 2021.12.08 |
람다(Lambda) (0) | 2021.11.28 |
예외 처리(exception handling) (0) | 2021.08.02 |
#5 생성자(Constructor) (0) | 2021.04.28 |
댓글