java / / 2023. 1. 26. 15:35

Java Stream의 orElse와 orElseGet 차이

Java 8의 Optional에 보면 orElseorElseGet 두 가지 메소드가 존재하는데 무슨 차이가 있을까?

아래 Optional 클래스를 보면 두 개의 메소드를 확인할 수 있다.

public T orElse(T other) {
  return value != null ? value : other;
}

public T orElseGet(Supplier<? extends T> other) {
  return value != null ? value : other.get();
}

orElse는 값이 null일 경우 T 타입을 반환해주고 orElseGet은 값이 null인 경우 Supplier에서 값을 꺼내서 리턴한다.
반환되는 타입도 T 타입으로 같으니 null일 경우 받는 매개변수만 다른것일까?

이 두 가지 메소드는 잘 구분하여 사용해야 한다고 구글링에서 많이 이야기한다. 그래서 실제 동작을 테스트 해보았다.

결론은 아래와 같다.

  • orElse는 리턴값이 null 여부와 상관없이 항상 호출된다.
  • orElseGet은 리턴값이 null인 경우만 호출된다.

아래는 테스트 코드이다.

orElse

@Test
public void orElseTest() {
  String name = "hong";
  String result = Optional.ofNullable(name).orElse(getDefault());
  System.out.println(result);
}

private String getDefault() {
  System.out.println("no name");
  return "no name";
}
  // 출력 메시지
  no name
  hong

여기서 orElse 파라미터는 값이 null이 아닐 경우에도 실행된다는 것을 확인할 수 있다.

orElseGet

@Test
public void orElseGetTest() {
  String name = "hong";
  String result = Optional.ofNullable(name).orElseGet(this::getDefault);
  System.out.println(result);
}

private String getDefault() {
  System.out.println("no name");
  return "no name";
}
// 출력 메시지
hong

orElseGet은 인수로 Supplier를 받는데 Supplier가 매개변수로 넘겨질 때는 Optional 값이 존재하지 않을때만 실행된다.

위의 예에서 볼 수 있듯이 orElse인 경우는 null 여부와 상관없이 무조건 호출 되므로 조심해서 사용해야 한다.
예를 들면 리턴값이 null인 경우 DB에 특정 정보를 update한다던가, 이벤트를 전송하는 등의 작업은 하지 않아야 한다.

// 이렇게 사용하면 안된다.
public User findUser(String userId) {
  return userRepository.findById(userId).orElse(createUser(userId)); // 
}

private void createUser(String userId) {
  userRepository.save(new User(userId)); 
}



반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유