java

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 ()`

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElseGet-java.util.function.Supplier-

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.