Open ahah525 opened 1 year ago
값이 있으면 값을 반환하고, 없으면 기본값을 반환한다.
값
을 받는다.@Test
@DisplayName("[orElse] null이 아닌 경우")
void t1() {
String userEmail = "user1@naver.com";
String result = Optional.ofNullable(userEmail)
.orElse(getUserEmail());
System.out.println(result);
}
Optional.ofNullable()
이 호출되고 value가 "user1@naver.com"
인 Optional
객체 생성getUserEmail()
이 호출되고 반환값을 orElse()
파라미터로 전달orElse()
가 호출되고 value가 null이 아니므로 "user1@naver.com"
를 반환getUserEmail() Called
user1@naver.com
@Test
@DisplayName("[orElse] null인 경우")
void t2() {
String userEmail = null;
String result = Optional.ofNullable(userEmail)
.orElse(getUserEmail());
System.out.println(result);
}
1~2는 1.2
와 동일
orElse()
가 호출되고 value가 null이므로 "user@naver.com"
를 반환getUserEmail() Called
user@naver.com
값이 있으면 값을 반환하고, 없으면 supplier의 결과값을 반환한다.
함수형 인터페이스(Supplier)
를 받는다.@Test
@DisplayName("[orElseGet] null이 아닌 경우")
void t3() {
String userEmail = "user1@naver.com";
String result = Optional.ofNullable(userEmail)
.orElseGet(this::getUserEmail);
System.out.println(result);
}
Optional.ofNullable()
이 호출되고 value가 "user1@naver.com"
인 Optional
객체 생성getUserEmail
함수 자체를 orElseGet()
파라미터로 전달orElse()
가 호출되고 value가 null이 아니므로 getUserEmail()
이 실행되지 않고 "user1@naver.com"
를 반환user1@naver.com
@Test
@DisplayName("[orElseGet] null인 경우")
void t4() {
String userEmail = null;
String result = Optional.ofNullable(userEmail)
.orElseGet(this::getUserEmail);
System.out.println(result);
}
1~2는 1.2
동일
orElse()
가 호출되고 value가 null이므로 getUserEmail()
가 실행되어 "user@naver.com"
를 반환getUserEmail() Called
user@naver.com
User
의 name
이 unique 하다고 가정한다.
DB에 해당 name
을 가진 User
가 있든 없든 createUserWithName()
이 무조건 호출되기 때문에 중복된 name
인 경우 DB에 save 할 때 오류가 발생한다.
public User findByName(String name) {
return userRepository.findByName(name)
.orElse(createUserWithName(name));
}
private User createUserWithName(String name) {
User user = new User(name);
return userRepository.save(user);
}
DB에 해당 name
을 가진 User
가 있는 경우에는 조회된 User
객체를 반환하고 없는 경우에는 createUserWithName()
가 호출되어 새로 생성된 User
객체를 반환한다.
public User findByName(String name) {
return userRepository.findByName(name)
.orElseGet(() -> createUserWithName(name));
}
private User createUserWithName(String name) {
User user = new User(name);
return userRepository.save(user);
}
orElse
는 파라미터로 값
을 받고 orElseGet
은 함수형 인터페이스(Supplier)
를 받는다.orElse
와 orElseGet
의 가장 큰 차이점은 빈 Optional 에 대한 기본값을 언제 계산하는지이다.orElse(…)
에서 …
은 Optional의 value가 null이든 아니든 무조건 실행되기 때문에 값이 미리 존재하는 경우
즉, 이미 생성되었거나 계산된 값일 때
만 사용한다.orElseGet(…)
에서 …
은 Optional의 value가 null일 때만 실행되므로 값이 미리 존재하지 않는 경우
즉, 새로운 객체를 생성하거나 새로운 연산을 수행하는 경우
에 사용한다.
문제
지금까지 Optional의 값을 꺼낼 때 안전하지 않은
get()
보다는orElse()
주로 사용해왔다.책에서
orElseGet(Supplier<? extends T> other)는 orElse 메서드에 대응하는 게으른 버전의 메서드다
라고 간단하게 설명하고 있는데, 한 번도 사용해본적이 없어서 추가적인 학습이 필요다고 느꼈다.예제를 통해서 orElse와 orElseGet은 어떤 차이가 있는지 이해하고 어떠한 경우에 사용해야할 지 생각해보자.
관련 목차
참고자료