Разница между методами Optional.orElse() и orElseGet() в Java

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Optional.orElse() сразу выполняет переданный аргумент, что может повлечь нерациональное использование ресурсов при выполнении ресурсозатратных операций, если Optional содержит значение. Вывод: orElseGet() использует стратегию ленивых вычислений, сохраняя эффективность использования ресурсов и активируя переданный Supplier только в случае отсутствия значения в Optional.

Java
Скопировать код
String value = Optional.of("Привет, мир!").orElse(computeIntensiveOperation()); // "Привет, мир!" уже есть, но computeIntensiveOperation() все равно выполняется... Нерациональное использование ресурсов!

String efficientValue = Optional.of("Привет, мир!").orElseGet(() -> computeIntensiveOperation()); // "Привет, мир!" сохранён без лишних вычислений, именно этого мы и хотели!

В случае ресурсоёмких операций всегда предпочтительнее использовать orElseGet(). При работе с простыми данными и статическими значениями по умолчанию используйте orElse().

Расчет производительности

Использование orElse() и orElseGet() можно сравнить с работой двух кассиров в магазине, где у каждого свой подход к эффективности рабочего процесса. Ваше решение в пользу метода Джонни orElse() или Сьюзи orElseGet() может серьезно повлиять на экономичность работы магазина.

  • Состояние-зависимая логика: Если требуется предельно аккуратное изменение системного состояния, чтобы избежать нежелательных побочных эффектов, только orElseGet() предоставит вам полный контроль.
Java
Скопировать код
Optional.of("Сотрудник месяца").orElseGet(() -> {
    logStorePerformance(); // Логируется только при отсутствии награды, оставляя почтовый ящик руководителя свободным
    return "Попробуйте получить награду в следующем месяце";
});
  • Сетевые/Дисковые операции: Если для альтернативных значений требуются длительные вызовы или чтение с диска, orElseGet() исключит эти специфические операции, если они нежизненно не потребуются.

  • Синхронизация процессов: В многопоточных системах, где на первом плане производительность, orElseGet() позволит избежать усложнения взаимодействия потоков.

В итоге, применение orElseGet() аналогично экономии электроэнергии через отключение неиспользуемой бытовой техники, способствуя оптимизации работы приложения.

Лучшие практики – правильный выбор

Выбор между пешей прогулкой до ближайшего магазина и поездкой туда на автомобиле во многом зависит от объема и веса ваших планируемых покупок. Осознание последствий и компромиссов, которых требуют наши решения, поможет сделать правильный выбор:

orElse() на практике

  • Статические значения по умолчанию: Когда значения по умолчанию не требуют значительных ресурсов, orElse() будет оптимальным выбором.
Java
Скопировать код
final String regularCustomer = "Джон Доу";
String customer = Optional.ofNullable(customerName).orElse(regularCustomer);  // Статическое значение не расходует лишние ресурсы процессора
  • Быстрые и простые операции: Если операции выполняются быстро и имеют низкую сложность, нагрузка на JVM остаётся незначительной, а orElse() становится наилучшим вариантом.

Почему выбирают orElseGet()?

  • Наблюдение и ожидание: Если для резервного значения требуются сложные вычисления, то orElseGet() поможет эффективно контролировать расходы.
Java
Скопировать код
// База данных клиентов магазина обширна, давайте подождём
String shoppingCartOwner = Optional.ofNullable(customerID).orElseGet(StoreDatabase::getCustomerRecord);
  • Селективное логгирование: Регистрирует события только при отсутствующем Optional, делая журнал записей чистым и информативным.

Искусство выбора

Выбор между orElse() и orElseGet() не всегда очевиден, как выбор любимого вкуса мороженого. Он больше похож на чашу весов, где читаемость кода соперничает с оптимизацией производительности. При незначительных затратах на выполнение операции лучше выбрать простоту, а когда важна экономия ресурсов на выполнении ресурсоёмких задач, выбирайте OrElseGet().

Визуализация

Представьте, что вы зашли в закусочную. Какой бы выбор вы не сделали?

Markdown
Скопировать код
Вариант 1: Готовый к подаче бургер 🍔 (быстро и предсказуемо)
Вариант 2: Бургер, приготовленный на заказ 🥘 (свежесть и учёт ваших предпочтений)

Optional.orElse() – это словно готовый бургер, уже ожидающий вас:

Markdown
Скопировать код
Подаётся сразу, **даже если вы ещё не проголодались**:
- Приготовлен заранее, остаётся горячим 🍔 
- Возможно, потеряет свойство свежести, если его сразу не съесть

Optional.orElseGet() – это бургер, приготовленный специально для вас:

Markdown
Скопировать код
Готовится по мере вашего прихода:
- Свежий, сделанный на заказ 🥘 
- Позволяет избежать лишних отходов и точно учитывает ваши потребности

Основное отличие:

Markdown
Скопировать код
`orElse()`: Готов заранее и готов к употреблению, но рискует потерять свежесть и качество.
`orElseGet()`: Приготавливает именно то, что вам нужно, без лишних потерь и с оптимальным использованием ресурсов!

Раскрытие аналогий с реальной жизнью

Для более понятного сравнения orElse() и orElseGet() рассмотрим жизненные ситуации, на примере которых можно оценить разницу:

Печать по требованию против печати большими тиражами

orElse() это как печать большого количества отчетов, которые могут оказаться ненужными — пустая трата бумаги и чернил. При этом, метод orElseGet() работает как принтер, печатающий отчеты только по мере их запрашивания, что является более рациональным использованием ресурсов.

Энергосберегающие устройства

Применение orElse() похоже на оставление включенного света и бытовой техники на случай их неожиданных потребностей. Это ведет к нерациональному использованию энергии. orElseGet(), напротив, аналогичен энергосберегающим устройствам, расходующим ресурсы только по необходимости.

Подача вызова экстренных служб

orElse() можно сравнить с вызовом скорой помощи при каждом подозрении на возможное происшествие. orElseGet(), наоборот, представляет собой более взвешенное решение: скорая помощь приезжает только при подтверждении серьезной проблемы.

Полезные материалы

  1. Oracle Docs – Optional JavaDocСамый авторитетный источник информации о классе Optional в Java.
  2. Stack Overflow – Разница между Optional.orElse() и Optional.orElseGet()Глубокое техническое обсуждение вопроса для понимания на прикладном уровне.
  3. Метод Optional.orElse() в Java с примерами – GeeksforGeeks — Здесь представлены примеры использования методов orElse и orElseGet.
  4. 26 советов по правильному использованию Optional в Java – DZone — Подробное руководство по эффективному применению класса Optional.
  5. Youtube – Видеоурок о различиях между Optional.orElse() и .orElseGet() — Содержательное видео с детальным объяснением и сравнением методов orElse и orElseGet.