자바 Optional 공부하기 (1편)
2023. 12. 1. 22:06ㆍBACKEND
728x90
Optional 공부하기
이직 후 회사에서 스프링부트와 JPA를 사용하는데
자바스크립트에 익숙했던 나에게 자바문법이 익숙하지 않고 생각처럼 되지않는 경우가 많았는데 가장 헷갈리는게 Optional 이였다.
Optional을 학습해 보자
Optional의 특징
- 값이 있거나 없음을 표현한다.
- null을 대체한다.
- 자바 8 버전에서 추가 되었다.
if(sid != null && !sid.isEmpty()) {
map.put("sid", sid);
}
if(utcTim != null && !utcTim.isEmpty()) {
map.put("utcTim", Double.parseDouble(utcTim));
}
if(rsltTTC != null && !rsltTTC.isEmpty()) {
map.put("rsltTTC", Double.parseDouble(rsltTTC));
}
if(rsltDir != null && !rsltDir.isEmpty()) {
map.put("rsltDir", Integer.parseInt(rsltDir));
}
if(rsltStt != null && !rsltStt.isEmpty()) {
map.put("rsltStt", Integer.parseInt(rsltStt));
}
if(notiTyp != null && !notiTyp.isEmpty()) {
map.put("notiTyp", Integer.parseInt(notiTyp));
}
if(hstId != null && !hstId.isEmpty()) {
map.put("hstId", Integer.parseInt(hstId));
}
if(hstTyp != null && !hstTyp.isEmpty()) {
map.put("hstTyp", Integer.parseInt(hstTyp));
}
위 내용 같은 IF지옥을 벗어날 수 있다.
Optional 생성
- Optinal.of() -> null이 아닌 값을 생성할 때 사용 한다. (null이면 NullPointerException 에러 발생)
- Optional.ofNullable() -> null 일 수 있는 값을 생성할 때 사용 한다.
- Optional.empty() -> null이 아니라 빈값을 넣고 싶은 경우 empty()를 사용 한다.
Optional 값 가져오기
- get()을 사용하면 된다 (값이 없는데 get()을 사용하면 NoSuchElementException 에러 발생)
값이 있는지 없는지 체크하기
- isPresent() -> 값이 있는지 확인
- isEmpty() -> 값이 없는지 확인한다. (자바11 이상부터 가능, isPresent가 false면 값이 없는 의미긴 하다.)
값이 있으면 동작 하기
- ifPresent() -> 값이 있으면 첫번째 인자로 넘어오는 콜백 함수를 실행 한다 -> opt.ifPresent(value -> doSome(value));
- ifPresentOrElse() -> 값이 있으면 첫번째 인자 콜백 함수 실행, 없으면 두번째 인자 함수 실행 -> opt.ifPresentOrElse((value) -> doSome(value), () -> doOther())
값이 없을 때 다른 값 사용
String myName = Optional.ofNullable(name).orElse("default name");
- orElse -> 값 자체를 리턴한다 -> opt.orElse("default")
- orElseGet -> 값 자체를 리턴하는데 값이 null인 경우에만 콜백함수를 실행 하고 값을 리턴한다. -> opt.orElseGet(() -> "default")
- or -> 값이 없을 때 옵셔널을 리턴한다. -> opt.or(() -> Optional.of("default"))
값이 없으면 익셉션을 발생하고 값이 있으면 값 리턴
- orElseThrow
Optional<Member> opt = repository.findById("id");
Member m = opt.orElseThrow(() -> new NoMemberException()) // 값이 없으면 Exception, 값 있으면 findById를 한 결과물 리턴
// opt에 값이 있다면 m에는 findById를 한 값이 담겨 있다.
map - Optional에 담겨있는 값을 변경
- map을 사용해 Optional이 담긴 값을 하나씩 꺼내와 변형할 수 있다. (자바스크립트 에서도 map을 사용하면 새로운 array 리턴)
- map은 옵셔널을 리턴한다.
- 값이 없는 Optional에 map을 사용하면 아무 동작도 하지 않고 빈 Optional을 리턴한다.
// 각각 map을 돌려서 변수로 담아줄 수도 있고
Optional<Member> memOpt = ...;
Optional<LocalDate> birthOpt = memOpt.map(mem -> mem.getBirthday());
Optional<Integer> pdOpt = birthOpt.map(birth -> cal(birth));
// map을 체인으로 사용할 수도 있다
Optional<Integer> pdOpt2 =
memOpt.map(mem -> mem.getBirthday())
.map(birth -> cal(birth));
filter
- 조건을 충족하면 값 그대로 리턴
- 충족하지 못 하면 빈 Optional 리턴
Optional<String> strOpt = ...;
Optional<String> filtered =
strOpt.filter(str -> str.length() > 3)
.ifPresent(str -> System.out.println(str));
Optional을 사용하며 주의하기
Optional에 담길 값이 int, long, double이라면 Boxing/Unboxing이 발생하는 Optional, Optional, Optional을 사용하지 말고, OptionalInt, OptionalLong, OptionalDouble을 사용하자.
// 안 좋음
Optional<Integer> count = Optional.of(38); // boxing 발생
for (int i = 0 ; i < count.get() ; i++) { ... } // unboxing 발생
// 좋음
OptionalInt count = OptionalInt.of(38); // boxing 발생 안 함
for (int i = 0 ; i < count.getAsInt() ; i++) { ... } // unboxing 발생 안 함
'BACKEND' 카테고리의 다른 글
javascript, async/await 공부하기 (1편) (0) | 2023.12.14 |
---|---|
자바 벼락치기 공부하기 (1) | 2023.12.08 |
TypeScript 공부하기 (1) | 2023.11.29 |
스프링 AOP 공부하기 (1) | 2023.11.28 |
Node.js - sequelize ORM 알아보기 (1) | 2023.11.26 |