orElse выполняется всегда, даже когда Optional не пуст
Кандидаты уверенно рассказывают про Optional, но спотыкаются на разнице между orElse и orElseGet. На бумаге они выглядят одинаково — оба дают значение по умолчанию, если Optional пуст. На практике разница в том, когда вычисляется это значение по умолчанию.
orElse(value) получает аргумент заранее, до любой проверки — выражение внутри вызывается всегда, даже если Optional уже содержит значение и результат никому не нужен. orElseGet(supplier) вызывает поставщика только тогда, когда значения действительно нет.
Optional user = repository.findById(id);
// loadDefaultUser() выполнится всегда, // даже если user присутствует User result = user.orElse(loadDefaultUser());
// defaultUser() выполнится только при пустом Optional User result2 = user.orElseGet(this::loadDefaultUser);
Если loadDefaultUser() — это поход в БД или внешний сервис, orElse выполняет его на каждый вызов метода, независимо от результата. На собесе это обычно подают как вопрос про производительность: «почему метод с orElse(fetchFromDb()) медленнее, чем кажется из кода».
Правило простое: если выражение по умолчанию дешёвое — orElse читается проще. Если это вызов метода с побочным эффектом или стоимостью — только orElseGet.
Тренажёр: 900+ вопросов и задач, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки