A: Ich suche Punkte im dreidimensionalen Raum. Zum Beispiel: (1.0, 0.5, 0.2).
B: Ein weiteres Beispiel wäre (3.5, 1.7776, 1242342.5674)
A: Nein nein, die sollten schon im Einheitswürfel liegen!
Ich denke, es kommt stark darauf an, welche „Muster“ in der Codebasis vorkommen, und wie man die „idiomatisch“ oder „schön“ durch Optional ersetzen kann (oder will? oder sollte?).
Ich hatte irgendwann mal ein paar Optionals-Methoden erstellt, die mit „dem“ Optional
nichts zu tun haben, aber ggf. auch dadurch ersetzt werden könnten. Sowas wie
Map<K, V> map = Optional.ofNullable(input).orElse(Collections.emptyMap());
kann man schreiben, aber wenn das 100 mal vorkommt, ist
Map<K, V> map = Optionals.of(input);
eben einfacher…
Analog dazu könnte man, wenn es sehr oft vorkommt, bei
Optional.of(foo)
.filter(Bar.class::isInstance)
.map(Bar.class::cast)
.map(...);
das mehrfache Auftreten von Bar.class
störend finden - nicht zuletzt auch im Sinne von „finde den Fehler“:
Optional.of(foo)
.filter(Bar.class::isInstance)
.map(Baz.class::cast)
.map(...);
und sich sowas wie
Optionals.ifType(foo, Bar.class) // Liefert ein (hart getyptes) Optional<Bar>
.map(...)
schustern.
Der Grund, warum dein Vorschlag auf Skepsis stößt, ist aber (vermutlich allgemein, und speziell) bei mir: Ich finde man sollte Optional
NICHT als „drop-in-replacement für if
-Abfragen“ einsetzen.
Brian Goetz hat zu Optional
gesagt:
Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent „no result“, and using null
for such was overwhelmingly likely to cause errors.
Das könnte in deinem Beispiel der Fall sein. Aber da das Beispiel durch die Platzhalternamen nicht mehr so viel aussagt drängt sich die Frage auf, die ich immer versuche, mir (bewußt naiv) zu stellen: Wer soll das wann und wo und wie verwenden?
Wenn dein skizziertes Beispiel so verwendet wird
Foo foo = obtainFoo();
Optional<Plonk> optionalPlonk = createPlonk(foo);
if (optionalPlonk.isPresent()) {
Plonk plonk = optionalPlonk.get();
process(plonk);
}
dann ist offenbar irgendwo irgendwas ganz, ganz Sche!ße gelaufen. D.h. wenn die ganze createPlonk
-Methode und die Verantwortung für die darin (egal wie!) mit dem Optional
umgesetzte Prüfung auch dem Aufrufer überlassen könnte oder sollte, stellen sich manche Fragen ja gar nicht…
Ansonsten: Allgemeine „Idiome“ wären vielleicht Sachen wie „Wie verwandle ich eine Map<K, Optional<V>>
in eine Map<K, V>
?“. Aber das würde ich eher als „Snippets, wie man etwas (geschickt) macht“ bezeichnen…