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 — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки