본문 바로가기
JAVA/기본

Optional

by 히포파타마스 2021. 12. 3.

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

댓글