티스토리 뷰
Optional : 오직 값 한 개가 들어 있을수도, 없을 수도 있는 컨테이너
ex ) 자바 프로그래밍에서 NulllPointException을 보게 될 때가 있다
package java8study;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class App3 {
public static void main(String[] args) {
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(2, "spring data jpa", true));
springClasses.add(new OnlineClass(3, "spring mvc", false));
springClasses.add(new OnlineClass(4, "spring core", false));
springClasses.add(new OnlineClass(5, "rest api development", false));
OnlineClass springBoot = new OnlineClass(1, "spring boot", true);
Duration studyDuration = springBoot.getProcess().getStudyDuration();
System.out.println("studyDuration :" + studyDuration);
}
}
이럴경우 보통
Progress progress = springBoot.getProcess();
if(progress !=null){
System.out.println(progress.getStudyDuration());
}
public Progress getProcess() {
if(this.process == null){
throw new IllegalStateException();
}
return process;
}
이런 두가지 방식으로 처리를 하는데 Optional을 이럴때 쓰면 더 명시적으로 정리가 됨
주의점
- 리턴 타입으로만 쓰기를 권장
- Optional을 리턴하는 메소드에서 null을 리턴하지말자 -> optional을 쓰는 이유가 없어짐
- 프리미티브 타입용 Optional이 따로 있다 ex) Optionalint, OptionalLong ....
- Collection, Map, Stream Array, Optional은 Optional로 감싸지 말것 -> 이 자체만으로도 비어있는지 판단할수 있는 인스턴스들
isPresent() : Optional에 값이 있는지 없는지 확인
package java8study;
import com.fasterxml.jackson.core.JsonToken;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class App3 {
public static void main(String[] args) {
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(5, "rest api development", false));
Optional<OnlineClass> optional = springClasses.stream()
.filter(oc -> oc.getTitle().startsWith("jpa"))
.findFirst();
boolean present = optional.isPresent();
System.out.println(present);
}
}
- 변수를 추출해줄때 "jpa"으로 시작되는게 있을수도 있고, 없을수도 있어서 알아서 Optional로 선언해준다
Optional에 있는 값 가져오기
optional.get()을 쓰면 되는데 값이 없을 경우
오류뜸
이럴때 쓰는것들
ifPresent() : 값이 있는경우 그 값을 가지고 ~~~ 하라
optional.ifPresent(oc->{
System.out.println(oc.getTitle());
});
값이 있으면 제목을 출력하라
orElse(), orElseGet() : 있으면 가져오고 없을경우 ~~~을 하라
package java8study;
import com.fasterxml.jackson.core.JsonToken;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class App3 {
public static void main(String[] args) {
List<OnlineClass> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(5, "rest api development", false));
Optional<OnlineClass> optional = springClasses.stream()
.filter(oc -> oc.getTitle().startsWith("jap"))
.findFirst();
OnlineClass onlineClass = optional.orElse(createNewClass());
OnlineClass onlineClass2 = optional.orElseGet(()->createNewClass());
}
private static OnlineClass createNewClass() {
System.out.println("creating new online class");
return new OnlineClass(10,"new class", false);
}
}
- 값이 있으면 가져오고 없으면 createNewClass 실행하라
- 근데 orElse같은 경우에는 값이 있어도 createNewClass가 실행 되기때문에 orElseGet을 쓰는게 더 좋을듯?
.orElseThrow() : 값이 있는 경우 가져오고 없는 경우 에러를 던져라
OnlineClass onlineClass = optional.orElseThrow(()->{
return new IllegalStateException();
});
Optional에 있는 값 걸러내기
Optional<OnlineClass> onlineClass =optional.filter(oc->!oc.isClosed());
System.out.println(onlineClass.isEmpty());
- 필터에 값이 해당 안되면 비어있는 optional이 나온다
Optional 형태 변환
Optional<Optional<Progress>> progress = optional.map(OnlineClass::getProcess);
Optional<Progress> progress1 = progress.orElse(Optional.empty());
Optional<Progress> progress2 = optional.flatMap(OnlineClass::getProcess);
- Map일때 flatMap을 사용하면 편리하게 꺼낼수 있음
참고
OnlineClass.java
package java8study;
public class OnlineClass {
private Integer id;
private String title;
private boolean closed;
private Progress process;
public OnlineClass(Integer id, String title, boolean closed) {
this.id = id;
this.title = title;
this.closed = closed;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isClosed() {
return closed;
}
public void setClosed(boolean closed) {
this.closed = closed;
}
public Progress getProcess() {
////
if(this.process == null){
throw new IllegalStateException();
}
return process;
}
public void setProcess(Progress process) {
this.process = process;
}
}
Progress.jasva
package java8study;
import java.time.Duration;
public class Progress {
private Duration studyDuration;
private boolean finished;
public Duration getStudyDuration() {
return studyDuration;
}
public void setStudyDuration(Duration studyDuration) {
this.studyDuration = studyDuration;
}
}
강의 : 인프런 더 자바, Java8
'Java' 카테고리의 다른 글
[Java8] CompletableFuture-Concurrent 프로그래밍2. Execurtors (0) | 2021.12.08 |
---|---|
[Java8] CompletableFuture-Concurrent 프로그래밍1. 스레드 (0) | 2021.12.07 |
[Java8] Stream API 예제 (0) | 2021.07.10 |
[Java8] Stream API (0) | 2021.07.10 |
[Java8] API의 기본 메소드와 스태틱 메소드 Iterable, Collection (0) | 2021.07.10 |
- Total
- Today
- Yesterday