El funcionamiento opcional de Java de orElse no es como si no
(3)
La salida es correcta,
Optional.orElse()
ejecutará siempre la acción else.
(la expresión que proporciona) Use
orElseGet()
que solo llama a la función si
Optional.isPresent == false
- para la salida deseada:
Diferencia entre `Optional.orElse ()` y `Optional.orElseGet ()`
En Opcional, mientras que el método opcional.orElse es call, independientemente de que el elemento esté presente o no se ejecute la parte orElse, no se comporta como la condición if else.
En el siguiente código, si ve en el Caso 1, tanto getNullPoJo como getDefaultPoJo se ejecutan desde que getNullPoJo regresará vacío Opcional
En el caso 2, donde obtendrá un opcional con valor cargado (de getLoadedPoJo), también se ejecutará getDefaultPoJo
Sólo estoy tratando de entender el funcionamiento de opcional.orElse.
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;
}
La salida actual es:
Ejecutando getNullPoJo
Ejecutando getDefaultPoJo
pojo1 Got Default
Ejecutando getLoadedPoJo
Ejecutando getDefaultPoJo
pojo2 se cargó
Mi salida esperada es:
Ejecutando getNullPoJo
Ejecutando getDefaultPoJo
pojo1 Got Default
Ejecutando getLoadedPoJo
pojo2 se cargó
No quiero que la llamada a getDefaultPoJo en el caso 2
Use
orElseGet()
para evitar evaluar
getDefaultPoJo()
cuando la
Optional
no esté vacía:
PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());
getNullPoJo().orElse(getDefaultPoJo());
Es una cadena de métodos, y todos los métodos de esta cadena se ejecutarán, sin importar cómo funcione la API subyacente.
1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)
Para ejecutar un método, sus parámetros reales deben ser evaluados.
Para llamar a
orElse(getDefaultPoJo())
, se debe invocar
getDefaultPoJo()
también.
Esa es la razón por la que está obteniendo más de lo que esperaba.
Normalmente veras
.orElse(null);
.orElse(defaultValue);
donde
null
, y
defaultValue
son valores predefinidos que no requieren ningún cálculo.
Por otro lado, escribimos
.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());
donde
generateDefaultValue
y
calculateDefaultOutcome
son métodos que realizan algunos cálculos (los intensivos o los que no queremos ejecutar hasta el momento adecuado [su caso]).
Comparar,
.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);
donde
DEFAULT_POJO
es una variable inicializada antes de esta llamada de método, y
createDefaultPoJo()
es un método que crea una instancia predeterminada cada vez que se llama.