Prima di tutto controlla la dichiarazione di entrambi i metodi.
1) OrElse: esegue la logica e passa il risultato come argomento.
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: esegue la logica se il valore all'interno dell'opzionale è nullo
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Qualche spiegazione sulla dichiarazione di cui sopra:
l'argomento di "Optional.orElse" viene sempre eseguito indipendentemente dal valore dell'oggetto in facoltativo (null, vuoto o con valore). Quando si utilizza "Optional.orElse", tenere presente sempre il punto sopra menzionato, altrimenti l'uso di "Optional.orElse" può essere molto rischioso nella seguente situazione.
Rischio-1) Problema di registrazione: se il contenuto all'interno di orElse contiene un'istruzione di registro: in questo caso, finirai per registrarlo ogni volta.
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
Rischio-2) Problema di prestazione: se il contenuto all'interno di orElse richiede molto tempo : il contenuto che richiede molto tempo può essere qualsiasi operazione di I / o chiamata DB, chiamata API, lettura file. Se inseriamo tali contenuti in orElse (), il sistema finirà per eseguire un codice inutile.
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
Rischio-3) Problema di stato o bug illegale: se il contenuto all'interno di orElse sta mutando lo stato di un oggetto: potremmo usare lo stesso oggetto in un altro posto, diciamo all'interno della funzione Optional.map e ci può mettere in un bug critico.
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;
}
Quindi, quando possiamo andare con orElse ()?
Preferisci usare orElse quando il valore predefinito è un oggetto costante, enum. In tutti i casi precedenti possiamo andare con Optional.orElseGet () (che viene eseguito solo quando Optional contiene un valore non vuoto) invece di Optional.orElse (). Perché?? In orElse, passiamo il valore del risultato predefinito, ma in orElseGet passiamo il fornitore e il metodo del fornitore viene eseguito solo se il valore in Opzionale è nullo.
Key takeaway da questo:
- Non utilizzare "Optional.orElse" se contiene un'istruzione di registro.
- Non utilizzare "Optional.orElse" se contiene una logica che richiede molto tempo.
- Non utilizzare "Optional.orElse" se sta mutando uno stato dell'oggetto.
- Usa "Optional.orElse" se dobbiamo restituire una costante, enum.
- Preferisci "Optional.orElseGet" nelle situazioni menzionate nei punti 1,2 e 3.
Ho spiegato questo nel punto 2 ( "Optional.map/Optional.orElse"! = "If / else" ) il mio blog medio. Utilizzare Java8 come programmatore e non come programmatore
orElseGet
chiama il fornitore solo se il valore è assente.