Ответ 1
Используйте orElseGet()
чтобы избежать оценки getDefaultPoJo()
когда Optional
не пуст:
PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());
В Optional, в то время как метод option.orElse является вызовом, независимо от того, присутствует ли элемент или не выполнена часть orElse, он не ведет себя как условие if else.
В приведенном ниже коде, если вы видите в случае 1, оба getNullPoJo и getDefaultPoJo выполняются, так как getNullPoJo вернет пустой Необязательно
В случае 2, где вы получите Optional с загруженным значением (из getLoadedPoJo), также вы получите getDefaultPoJo
Я просто пытаюсь понять работу по желанию.
public static void main (String [] a) {
PoJo poJo1=getNullPoJo().orElse(getDefaultPoJo());//Case 1
System.out.println("pojo1 Got "+poJo1.getVariable());
PoJo poJo2=getLoadedPoJo().orElse(getDefaultPoJo());//Case 2
System.out.println("pojo2 Got "+poJo2.getVariable());
}
private static Optional<PoJo> getNullPoJo() {
System.out.println("Executing getNullPoJo");
Optional<PoJo> optional=Optional.empty();
return optional;
}
private static Optional<PoJo> getLoadedPoJo() {
System.out.println("Executing getLoadedPoJo");
PoJo poJo =new PoJo();
poJo.setVariable("Loaded");
Optional<PoJo> optional=Optional.of(poJo);
return optional;
}
private static PoJo getDefaultPoJo() {
System.out.println("Executing getDefaultPoJo");
PoJo poJo =new PoJo();
poJo.setVariable("Default");
return poJo;
}
Текущий выход:
Выполнение getNullPoJo
Выполнение getDefaultPoJo
pojo1 получил по умолчанию
Выполнение getLoadedPoJo
Выполнение getDefaultPoJo
pojo2 получил загружен
Мой ожидаемый результат:
Выполнение getNullPoJo
Выполнение getDefaultPoJo
pojo1 получил по умолчанию
Выполнение getLoadedPoJo
pojo2 получил загружен
Я не хочу, чтобы вызов getDefaultPoJo в случае 2
Используйте orElseGet()
чтобы избежать оценки getDefaultPoJo()
когда Optional
не пуст:
PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());
getNullPoJo().orElse(getDefaultPoJo());
Это цепочка методов, и каждый метод в этой цепочке будет выполняться независимо от того, как должен работать базовый API.
1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)
Чтобы выполнить метод, его фактические параметры должны быть оценены. Для вызова orElse(getDefaultPoJo())
, getDefaultPoJo()
должен быть вызван. Вот почему вы получаете больше, чем ожидали.
Обычно вы увидите
.orElse(null);
.orElse(defaultValue);
где null
и defaultValue
- это предопределенные значения, которые не требуют каких-либо вычислений.
С другой стороны, мы пишем
.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());
где generateDefaultValue
и calculateDefaultOutcome
- это методы, которые выполняют некоторые вычисления (интенсивные или те, которые мы не хотим выполнять до подходящего момента [ваш случай]).
Сравните,
.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);
где DEFAULT_POJO
- это переменная, инициализированная до вызова этого метода, а createDefaultPoJo()
- это метод, который создает экземпляр по умолчанию при каждом вызове.
Вывод правильный, Optional.orElse()
всегда выполнит else-действие. (выражение, которое вы предоставляете) Использование orElseGet()
-which вызывает функцию, только если Optional.isPresent == false
- для желаемого результата: