Uwielbiam to, że optionals są teraz w standardowej bibliotece Java. Ale pojawia się jeden podstawowy problem, na który nie mam pojęcia, jak rozwiązać problem w najlepszy (najłatwiejszy do odczytania i zrozumienia, najładniejszy i najkrótszy) sposób:Jak powrócić, gdy opcja jest pusta?
Powrót z metody, gdy opcjonalny jest pusty?
Szukam ogólnego rozwiązania, które działa dla różnych kombinacji liczb opcji i rozmiarów bloków kodu.
W poniższych przykładach postaram się pokazać, co mam na myśli:
void m1() {
// When I get an optional:
Optional<String> o = getOptional();
// And want to return if it's empty
if (!o.isPresent()) return;
// In the whole rest of the method I have to call Optional.get
// every time I want the value:
System.out.println(o.get());
// Which is pretty ugly and verbose!
}
void m2() {
// If I instead return null if a value is absent:
String s = getNullabe();
if (s == null) return;
// Then I can use the value directly:
System.out.println(s);
}
To pytanie jest o tym, jak uzyskać dobry aspekt obu powyższych przykładach: typ bezpiecznie opcjonalnego i zwięzłości typów nullable.
Reszta przykładów ilustruje to bardziej.
void m3() {
// If I on the other hand want to throw on empty that's pretty and compact:
String s = getOptional()
.orElseThrow(IllegalStateException::new);
System.out.println(s);
}
void m4() {
Optional<String> o = getOptional();
if (!o.isPresent()) return;
// I can of course declare a new variable for the un-optionalised string:
String s = o.get();
System.out.println(s);
// But the old variable still remains in scope for the whole method
// which is ugly and annoying.
System.out.println(o.get());
}
void m5() {
// This is compact and maybe pretty in some ways:
getOptional().ifPresent(s -> {
System.out.println(s);
// But the extra level of nesting is annoying and it feels
// wrong to write all the code in a big lambda.
getOtherOptional().ifPresent(i -> {
// Also, more optional values makes it really weird and
// pretty hard to read, while with nullables I would
// get no extra nesting, it would looks good and be
// easy to read.
System.out.println("i: " + i);
// It doesn't work in all cases either way.
});
});
}
Optional<String> getOptional() {
throw new UnsupportedOperationException();
}
Optional<Integer> getOtherOptional() {
throw new UnsupportedOperationException();
}
String getNullabe() {
throw new UnsupportedOperationException();
}
Jak mogę wrócić z metody, jeżeli opcja jest pusta, bez konieczności korzystania get
w pozostałej części metody, bez deklarowania dodatkową zmienną i bez dodatkowych poziomów zagnieżdżenia bloku?
Albo, jeśli nie można tego wszystkiego uzyskać, jaki jest najlepszy sposób poradzenia sobie z tą sytuacją?
Naprawdę nie ma nic złego w 'if (optional.isPresent()) {...}'. 'Opcjonalne' dodaje więcej wartości semantycznej niż' null', więc misja została wykonana. Czytelność i zwięzłość często stanowią dobrą równowagę. "Ugly" i "verbose" są tutaj takimi przesadami. – Radiodef
@Lii, jeśli interesuje Cię bardziej ogólny przypadek (różne typy opcji i operacji), dodaj go do swojego pytania. Jest to inny przypadek użycia, jeśli masz te same typy i te same operacje. – user140547
to wszystkie szwy jak przykłady, w których użycie Opcjonalnego nie jest najlepszym rozwiązaniem ... –