Antes que nada, verifique la declaración de ambos métodos.
1) OrElse: ejecuta la lógica y pasa el resultado como argumento.
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: ejecuta la lógica si el valor dentro del opcional es nulo
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Alguna explicación sobre la declaración anterior:
El argumento de "Opcional.o Else" siempre se ejecuta independientemente del valor del objeto en opcional (nulo, vacío o con valor). Siempre tenga en cuenta el punto mencionado anteriormente al usar "Opcional.o Else", de lo contrario, el uso de "Opcional.o Else" puede ser muy arriesgado en la siguiente situación.
Riesgo-1) Problema de registro: si el contenido dentro o Else contiene alguna declaración de registro: en este caso, terminará registrándolo cada vez.
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
Riesgo-2) Problema de rendimiento: si el contenido interno o Else requiere mucho tiempo: el contenido intensivo de tiempo puede ser cualquier llamada de DB de operaciones de E / S, llamada de API, lectura de archivos. Si ponemos dicho contenido en orElse (), el sistema terminará ejecutando un código inútil.
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
Riesgo-3) Estado ilegal o problema de error: si el contenido dentro o Else está mutando algún estado de objeto: podríamos estar usando el mismo objeto en otro lugar, digamos dentro de la función Opcional.map y nos puede poner en un error crítico.
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;
}
Entonces, ¿cuándo podemos ir con orElse ()?
Prefiere usar orElse cuando el valor predeterminado es algún objeto constante, enum. En todos los casos anteriores, podemos ir con Opcional.orElseGet () (que solo se ejecuta cuando Opcional contiene un valor no vacío) en lugar de Opcional.orElse (). ¿¿Por qué?? En orElse, pasamos el valor de resultado predeterminado, pero en orElseGet pasamos el Proveedor y el método del Proveedor solo se ejecuta si el valor en Opcional es nulo.
Conclusiones clave de esto:
- No use "Opcional.o Else" si contiene alguna instrucción de registro.
- No use "Opcional.o Else" si contiene una lógica que requiere mucho tiempo.
- No use "Opcional.o Else" si está mutando algún estado del objeto.
- Utilice "Opcional. O Else" si tenemos que devolver una constante, enum.
- Prefiera "Opcional.o ElseGet" en las situaciones mencionadas en los puntos 1,2 y 3.
He explicado esto en el punto 2 ( "Opcional.map/Optional.orElse"! = "If / else" ) mi blog medio. Use Java8 como programador, no como codificador
orElseGet
, llama al proveedor solo si no hay valor.