Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- JPA
- 페이징
- 서블릿 컨테이너
- DI
- Dead Letter Queue
- 쿠버네티스
- @ComponentScan
- AWS
- Web
- JPQL
- 스프링 부트
- docker compose
- MSA
- JdbcTemplate
- Spring Data JPA
- JWT
- redis
- Spring Container
- DLQ
- securitycontextholderfilter
- CORS
- 지연 로딩
- dockerhub
- docker
- mybatis
- Spring
- kafka
- @Transactional
- Routing Key
- 컨테이너
Archives
- Today
- Total
look-forest
Optional 본문
Optional 소개
Optional : 오직 값 한 개가 들어있을 수도 없을 수도 있는 컨네이너.
객체 Null 체크를 잊을 수 있기도 하고, 번거롭기도 해서 편의상 등장했다.
Optional은 클라이언트에 코드에게 명시적으로 빈 값일 수도 있다는 걸 알려주고, 빈 값인 경우에 대한 처리를 강제한다.
메소드에서 작업 중 특별한 상황에서 값을 제대로 리턴할 수 없는 경우 선택할 수 있는 방법
- 예외를 던진다. (비싸다, 스택트레이스를 찍어두니까.)
- null을 리턴한다. (비용 문제가 없지만 그 코드를 사용하는 클라이언트 코드가 주의해야 한다.)
- Optional을 리턴한다.
주의할 것
- 리턴값으로만 쓰자. 메소드 매개변수 타입, 맵의 키 타입, 인스턴스 필드 타입으로 쓰지 말자.
(매개변수, 필드 등에 null이 들어갈 수 있는데, null.ifPresent()를 사용하면 NPE 발생.. 의미가 없어진다.) - Optional을 리턴하는 메소드에서 null을 리턴하지 말자. Optional.empty()로 리턴해라.
(Optional을 사용하는 의미가 없다. null.ifPresent()를 사용하면 NPE 발생..) - Optional로 감쌀 객체가 Null일 수 있으면 ofNullable()을 사용하자.
- 프리미티브 타입용 Optional을 따로 있다. OptionalInt, OptionalLong,...
Optional.of(10)으로 만들면 boxing, unboxing이 일어나서 성능에 좋지 않다. - Collection, Map, Stream Array, Optional은 Opiontal로 감싸지 말 것.
이미 빈값인지 확인할 수 있는 컨테이너다. Optional로 두번 감쌀 이유가 없다.
public Optional<Progress> getProgress() {
return Optional.ofNullable(progress); //ofNullable : null일 수 있다. of로 만들면 null일 경우 NPE
}
Optional API
Optional 만들기
- Optional.of() -> 감쌀 객체가 null이면 NPE 발생
- Optional.ofNullable()
- Optional.empty()
Optional에 값이 있는지 없는지 확인하기
- Boolean isPresent()
- Boolean isEmpty() (Java 11부터 제공)
Optional에 있는 값 가져오기
- get() -> 만약 비어있는 Optional일 경우 NoSuchElementException 발생
=> 가급적 get을 쓰지말고 아래 API를 사용해라.
Optional에 값이 있는 경우에 do something
- ifPresent(Consumer)
optional.ifPresent(obj -> System.out.println(obj.getId()));
Optional에 값이 있으면 가져오고 없는 경우에
- T를 리턴 : orElse(T)
- do something : orElseGet(Supplier)
- 에러 발생 : orElseThrow(Supplier)
//JPA로 시작하는 수업이 없다면 비어있는 수업을 리턴하라.
OnlineClass onlineClassNull = optional.orElse(null); //여기서 객체 반환 선언하면, 값이 있는 경우도 실행. lazy하게 처리 불가.
//JPA로 시작하는 수업이 없다면 새로 만들어서 리턴하라.
OnlineClass onlineClassNew = optional.orElseGet(() -> new OnlineClass(6, "jpa", true)); //실행x. supplier는 lazy.
//JPA로 시작하는 수업이 없다면 에러를 던져라
OnlineClass onlineClassThrow = optional.orElseThrow(NoSuchElementException::new);
Optional에 들어있는 값 걸러내기
- Optional filter(Predicate)
Optional<OnlineClass> onlineClass = optional.filter(oc -> oc.getId() > 10);
Optional에 들어있는 값 변환하기
- Optional map(Function)
- Optional flatMap(Function): Optional 안에 들어있는 인스턴스가 Optional인 경우에 사용하면 편리하다.
//mapping 한 값도 Optional로 반환
Optional<Integer> optionalId = optional.map(OnlineClass::getId);
//map한 것이 Optional 타입이라면, Optional이 두번 감싸진다.
Optional<Optional<Progress>> progressOptional2 = optional.map(OnlineClass::getProgress);
//이럴 때 flatMap을 쓰면 Optional을 한번만 써준다.
Optional<Progress> progressOptionalFlat = optional.flatMap(OnlineClass::getProgress);
참고 자료 & 이미지 출처
더 자바, Java 8 (백기선 님)
'Java > 모던 자바(Java 8+)' 카테고리의 다른 글
| CompletableFuture (0) | 2024.11.09 |
|---|---|
| Date와 Time (0) | 2024.11.09 |
| Stream (0) | 2024.11.09 |
| 인터페이스의 변화 (0) | 2024.11.08 |
| 함수형 인터페이스와 람다 (2) | 2024.11.07 |