Optional часто используют, чтобы взять значение или подставить fallback:
String name = userName.orElse(loadDefaultName());
На первый взгляд всё нормально. Но
loadDefaultName() выполнится всегда, даже если внутри Optional уже есть значение.Например:
Optional<String> name = Optional.of("Alice");
String result = name.orElse(expensiveFallback());expensiveFallback() всё равно будет вызван.Если fallback дорогой: запрос в базу, чтение файла, HTTP-вызов или тяжёлый расчёт — это лишняя работа.
Для ленивого fallback есть
orElseGet():String result = name.orElseGet(() -> expensiveFallback());
Теперь fallback выполнится только если Optional пустой:
Optional<String> empty = Optional.empty();
String result = empty.orElseGet(() -> expensiveFallback());
Разница особенно заметна в сервисном коде:
User user = cachedUser.orElseGet(() -> loadFromDatabase(id));
Если пользователь уже есть в кэше, база не трогается.
А
orElse() лучше оставлять для простых готовых значений:String label = name.orElse("Anonymous");Если fallback нужно вычислять, используй orElseGet(). Если значение уже готово то orElse() вполне подходит.
👉 Java Ready | #совет
