Web Programming Language/JAVA

orElse vs orElseGet 차이점

manchesterandthecity 2025. 2. 12. 20:21

orElse vs orElseGet

Java에서 Optional<T>을 사용할 때, orElse와 orElseGet은 Optional이 비어 있을 경우 기본값을 제공하는 메서드이다.
하지만 두 메서드가 작동하는 방식에는 중요한 차이점이 있다.

핵심 차이:

  • orElse(T other): 기본값을 항상 계산하고, Optional이 비어 있으면 반환.
  • orElseGet(Supplier<? extends T> supplier): Optional이 비어 있을 때만 기본값을 계산.

1. orElse 동작 방식

기본값을 "항상" 계산하는 메서드

  • Optional이 값이 있든 없든 항상 orElse에 전달된 값이 평가(계산)된다.
  • 즉, Optional이 값이 있을 때도 불필요한 연산이 실행될 수 있다.

orElse 예제

public class OrElseExample {
    public static String getDefaultValue() {
        System.out.println("getDefaultValue() 호출됨");
        return "기본값";
    }

    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable("안녕하세요");

        String result = optional.orElse(getDefaultValue()); // getDefaultValue()가 실행될까?
        System.out.println("결과: " + result);
    }
}

실행 결과

getDefaultValue() 호출됨
결과: 안녕하세요

 

왜 이런 결과가 나왔을까?

  • Optional에는 "안녕하세요"라는 값이 이미 존재한다.
  • 그런데도 getDefaultValue()가 무조건 실행되었다.
  • 즉, 기본값이 필요하지 않더라도 연산이 발생하는 비효율적인 상황이 생길 수 있다.

2. orElseGet 동작 방식

기본값을 "필요할 때만" 계산하는 메서드

  • Optional이 비어 있을 때만 Supplier(람다 함수)를 실행한다.
  • 즉, 값이 존재하면 불필요한 연산을 하지 않는다.

orElseGet 예제

public class OrElseGetExample {
    public static String getDefaultValue() {
        System.out.println("getDefaultValue() 호출됨");
        return "기본값";
    }

    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable("안녕하세요");

        String result = optional.orElseGet(() -> getDefaultValue()); // getDefaultValue()가 실행될까?
        System.out.println("결과: " + result);
    }
}

실행 결과

결과: 안녕하세요

 

이번에는 getDefaultValue()가 실행되지 않았다!

  • Optional에 "안녕하세요"라는 값이 있으므로 기본값을 만들 필요가 없기 때문이다.
  • 즉, orElseGet은 연산을 최소화할 수 있도록 도와준다.

 

3. orElse vs orElseGet 비교

비교 표

메서드 기본값 평가 시점 최적화 가능 여  언제 사용해야 할까?
orElse(T other) 항상 평가됨 ❌ 비효율적
(불필요한 연산 가능)
기본값이 가벼운 경우
orElseGet(Supplier<? extends T> supplier) 필요할 때만 평가됨 ✅ 최적화 가능 기본값을 생성하는 연산이 무거운 경우
(DB 조회, 파일 읽기 등)

orElse의 문제점

Optional<String> optional = Optional.ofNullable("데이터 있음");
String result = optional.orElse(getDataFromDatabase()); // DB 조회가 필요할까?
  • Optional에 값이 있음에도 DB 조회가 실행됩니다!
  • 연산 비용이 큰 작업이 불필요하게 실행될 수 있습니다.

해결 방법 → orElseGet 사용

Optional<String> optional = Optional.ofNullable("데이터 있음");
String result = optional.orElseGet(() -> getDataFromDatabase()); // 필요할 때만 실행됨!
  • Optional이 비어 있을 때만 DB 조회가 실행됩니다.
  • 연산 비용이 큰 작업일 경우, 반드시 orElseGet을 사용하세요.

4. 실전 예제: 성능 차이 확인

orElse vs orElseGet 비교 실험

public class OrElseVsOrElseGet {
    public static String expensiveOperation() {
        System.out.println("💰 비용이 큰 연산 실행 중...");
        return "연산 결과";
    }

    public static void main(String[] args) {
        System.out.println("📌 `orElse` 사용:");
        Optional<String> optional1 = Optional.of("값 있음");
        String result1 = optional1.orElse(expensiveOperation());

        System.out.println("\n📌 `orElseGet` 사용:");
        Optional<String> optional2 = Optional.of("값 있음");
        String result2 = optional2.orElseGet(() -> expensiveOperation());
    }
}

실행 결과

📌 `orElse` 사용:
💰 비용이 큰 연산 실행 중...

📌 `orElseGet` 사용:
  • orElse는 값이 있어도 expensiveOperation()이 실행됨. (비효율적❌)
  • orElseGet은 값이 있으면 실행되지 않음. (최적화 가능✅)

 

5. 언제 orElse를 쓰고 언제 orElseGet을 써야 할까?

기본값이 간단한 값이라면 → orElse 사용

String result = optional.orElse("기본값");
  • "기본값"처럼 가벼운 값이라면 orElse가 편리함.

기본값을 생성하는 연산이 무겁다면 → orElseGet 사용

String result = optional.orElseGet(() -> getDataFromDatabase());
  • getDataFromDatabase()처럼 실행 비용이 큰 경우, orElseGet을 사용하여 불필요한 연산을 방지.

 

결론

  • orElse는 기본값 연산이 항상 실행되므로, 연산 비용이 크다면 orElseGet을 사용하는 것이 좋다.
  • orElseGet은 Optional이 비어 있을 때만 연산하므로, 불필요한 연산을 방지할 수 있다.
  • 성능 최적화를 위해 기본값을 미리 계산할 필요가 없는 경우 orElseGet을 적극 활용하자!

 

참조
https://ysjune.github.io/posts/java/orelsenorelseget/