Прежде всего, проверьте объявление обоих методов.
1) OrElse: выполнить логику и передать результат в качестве аргумента.
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: выполнить логику, если значение внутри необязательного равно нулю
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Некоторое объяснение вышеупомянутой декларации:
Аргумент «Optional.orElse» всегда выполняется независимо от значения объекта в необязательном порядке (null, пусто или со значением). При использовании «Optional.orElse» всегда учитывайте вышеупомянутый момент, в противном случае использование «Optional.orElse» может быть очень рискованным в следующей ситуации.
Риск-1) Проблема с журналированием: если содержимое внутри orElse содержит какой-либо оператор журнала: в этом случае вы будете регистрировать его каждый раз.
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
Риск-2) Проблема с производительностью: Если содержимое внутри orElse требует много времени : Содержимое, требующее много времени, может представлять собой любые операции ввода-вывода, вызов БД, вызов API, чтение файла. Если мы поместим такой контент в orElse (), система в итоге выполнит бесполезный код.
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
Риск-3) Недопустимое состояние или ошибка: если содержимое внутри orElse изменяет некоторое состояние объекта: мы можем использовать этот же объект в другом месте, скажем, внутри функции Optional.map, и это может привести к критической ошибке.
List<Model> list = new ArrayList<>();
Optional.of(getModel())
.map(x -> {
})
.orElse(get(list));
get(List < String > list) {
log.error("No Data found, Returning default");
list.add(defaultValue);
return defaultValue;
}
Тогда, когда мы можем пойти с orElse ()?
Предпочитайте использовать orElse, когда значением по умолчанию является некоторый константный объект enum. Во всех вышеупомянутых случаях мы можем использовать Optional.orElseGet () (который выполняется только тогда, когда Optional содержит непустое значение) вместо Optional.orElse (). Зачем?? В orElse мы передаем значение результата по умолчанию, но в orElseGet мы передаем Supplier, а метод Supplier выполняется только в том случае, если значение в Optional равно null.
Основные выводы из этого:
- Не используйте «Optional.orElse», если он содержит какой-либо оператор журнала.
- Не используйте «Optional.orElse», если он содержит лояльную по времени логику.
- Не используйте «Optional.orElse», если он изменяет некоторое состояние объекта.
- Используйте «Optional.orElse», если нам нужно вернуть константу, enum.
- Предпочитайте «Optional.orElseGet» в ситуациях, упомянутых в 1,2 и 3 пунктах.
Я объяснил это в пункте 2 ( «Optional.map/Optional.orElse»! = «If / else» ) моего среднего блога. Используйте Java8 как программист, а не как кодер
orElseGet
он вызывает поставщика, только если значение отсутствует.