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/