Przede wszystkim sprawdź deklarację obu metod.
1) OrElse: Wykonaj logikę i przekaż wynik jako argument.
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: Wykonaj logikę, jeśli wartość wewnątrz opcjonalnego jest pusta
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Kilka wyjaśnień na temat powyższej deklaracji:
Argument „Optional.orElse” zawsze jest wykonywany niezależnie od wartości obiektu w postaci opcjonalnej (null, pusta lub z wartością). Podczas korzystania z „Optional.orElse” zawsze miej na uwadze powyższy punkt, w przeciwnym razie użycie „Optional.orElse” może być bardzo ryzykowne w następującej sytuacji.
Ryzyko-1) Problem z logowaniem: Jeśli zawartość wewnątrz orElse zawiera jakieś oświadczenie dziennika: W takim przypadku będziesz go logować za każdym razem.
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
Ryzyko-2) Problem z wydajnością: jeśli zawartość wewnątrz orElse jest czasochłonna: treściochłonne mogą być dowolne operacje we / wy wywołanie DB, wywołanie API, odczyt pliku. Jeśli umieścimy taką treść w orElse (), system ostatecznie wykona kod bezużyteczny.
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
Ryzyko 3) Nielegalny stan lub błąd: jeśli zawartość wewnątrz orElse mutuje jakiś stan obiektu: Być może używamy tego samego obiektu w innym miejscu, powiedzmy w funkcji Optional.map i może to spowodować błąd krytyczny.
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;
}
Zatem, kiedy możemy przejść z orElse ()?
Preferuj użycie orElse, gdy wartością domyślną jest jakiś stały obiekt, wyliczanie. We wszystkich powyższych przypadkach możemy korzystać z Optional.orElseGet () (który działa tylko wtedy, gdy Optional zawiera niepustą wartość) zamiast Optional.orElse (). Czemu?? W orElse przekazujemy domyślną wartość wyniku, ale w orElseGet przekazujemy Dostawcę, a metoda Dostawcy jest wykonywana tylko wtedy, gdy wartość w Opcjonalnym jest równa null.
Najważniejsze rzeczy z tego:
- Nie używaj „Optional.orElse”, jeśli zawiera ona jakąkolwiek instrukcję dziennika.
- Nie używaj „Optional.orElse”, jeśli zawiera logikę czasochłonną.
- Nie używaj „Optional.orElse”, jeśli powoduje to mutację stanu niektórych obiektów.
- Użyj „Optional.orElse”, jeśli musimy zwrócić stałą, wyliczanie.
- Preferuj „Optional.orElseGet” w sytuacjach wymienionych w punktach 1,2 i 3.
Wyjaśniłem to w punkcie-2 ( „Optional.map/Optional.orElse”! = „If / else” ) mój średni blog. Używaj Java8 jako programisty, a nie kodera
orElseGet
go używasz , dzwoni do dostawcy tylko w przypadku braku wartości.