Warum findFirst() werfen einer NullPointerException, wenn das erste element, es findet null ist?
Warum hat dieser Wurf ein java.lang.NullPointerException
?
List<String> strings = new ArrayList<>();
strings.add(null);
strings.add("test");
String firstString = strings.stream()
.findFirst() //Exception thrown here
.orElse("StringWhenListIsEmpty");
//.orElse(null); //Changing the `orElse()` to avoid ambiguity
Das erste Element in strings
ist null
, das ist ein durchaus akzeptabler Wert. Darüber hinaus findFirst()
gibt ein Optional, das macht sogar mehr Sinn für findFirst()
handhaben zu können null
s.
EDIT: aktualisiert die orElse()
zu sein weniger zweideutig.
null ist nicht vollkommen akzeptabler Wert... mit "" statt
obwohl ich mit der
Ja, aber in java null ist nicht akzeptabel..mit der Abfrage auf null in die db
Ich vermute, dass durch die Zeit, die Sie rufen
obwohl ich mit der
String
hier, was ist, wenn es eine Liste, stellt eine Spalte in der DB? Der Wert der ersten Zeile dieser Spalte können null
.Ja, aber in java null ist nicht akzeptabel..mit der Abfrage auf null in die db
null
ist ein durchaus akzeptabler Wert in Java allgemein. Insbesondere ist es ein gültiges element für eine ArrayList<String>
. Wie jeder andere Wert, jedoch gibt es Einschränkungen auf das, was mit ihm getan werden kann. "Verwenden Sie nicht immer null
" nicht nützliche Ratschläge, wie Sie sich nicht vermeiden lässt.Ich vermute, dass durch die Zeit, die Sie rufen
findFirst()
, es gibt nichts, was Sie tun möchten.InformationsquelleAutor neverendingqs | 2015-09-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der Grund HIERFÜR ist die Verwendung von
Optional<T>
bei der Rückkehr. Optional, nicht enthalten darfnull
. Im wesentlichen, es bietet keine Möglichkeit der Unterscheidung von Situationen, die "es nicht gibt" und "es ist da, abernull
".Deshalb die Dokumentation verbietet ausdrücklich die situation, wenn
null
ausgewählt istfindFirst()
:Optional
. Wie auch immer, ich glaube, ich bin zu angrenzenden schimpfen - wenn die Sprache nicht unterstützt wird, es unterstützt es nicht.Absolut, mit ein
boolean
zur Unterscheidung dieser beiden Situationen würde durchaus Sinn machen. Für mich sieht es so aus, wie der Gebrauch vonOptional<T>
hier wurde eine fragwürdige Wahl.Ich kann mir nicht vorstellen, dass es eine gut aussehende alternative zu diesem, neben Ihre eigenen Rollen null, die ist nicht ideal entweder.
Ich landete schreiben Sie eine private Methode, wird der iterator von jedem
Iterable
geben, prüfthasNext()
, und gibt den entsprechenden Wert.Ich denke, es macht mehr Sinn, wenn
findFirst
Rückgabe eines leeren Optionalen Wert in den PO ' s FallInformationsquelleAutor dasblinkenlight
Als bereits diskutiert, die API-Designer nicht davon ausgehen, dass die Entwickler behandeln will
null
Werten und fehlenden Werten auf die gleiche Weise.Wenn Sie immer noch wollen, zu tun, können Sie tun es explizit durch anwenden der Sequenz
in den stream. Das Ergebnis wird ein leeres optional in beiden Fällen, wenn es keine erste element oder, wenn das erste element ist
null
. Also in Ihrem Fall, können Sieum eine
null
Wert, wenn das erste element ist entweder nicht vorhanden odernull
.Wenn Sie möchten, eine Unterscheidung zwischen diesen Fällen, können Sie einfach weglassen, die
flatMap
Schritt:Ist das nicht viel anders, um Ihre aktualisierte Frage. Sie müssen nur ersetzen
"no such element"
mit"StringWhenListIsEmpty"
und"first element is null"
mitnull
. Aber wenn Sie nicht wie die Bedingungen, die Sie erreichen können es auch gerne:Nun
firstString
wirdnull
wenn ein element vorhanden ist, abernull
und es wird"StringWhenListIsEmpty"
wenn kein element vorhanden ist.null
für entweder 1) das erste element istnull
oder 2) keine Elemente gibt es in der Liste. Ich habe aktualisiert die Frage zum entfernen der Mehrdeutigkeit.In der 3. code-Schnipsel, eine
Optional
zugeordnet werden könnennull
. DaOptional
soll ein "Wert-Typ", es sollte niemals null sein. Und ein Optionales sollten nie verglichen werden, indem==
. Kann der code nicht in Java 10 :)) oder Wann immer Wert-Typ eingeführt wird, um Java.href="http://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html" >Dokumentation nicht sagen, dass Referenzen zu Wert-Typen können nicht
null
und während Instanzen sollten nie verglichen werden, indem==
, die Referenz getestet werden kann fürnull
mit==
wie das ist, dasnull
. Ich kann nicht sehen, wie solch ein übergang zu "nienull
" sollten für die vorhandenen code, wie auch der default-Wert für alle Instanz-Variablen und array-Elemente istnull
. Der Schnipsel ist sicherlich nicht der beste code, aber weder ist die Aufgabe, der Behandlung vonnull
s als die gegenwärtigen Werte.siehe john rose - noch kann es verglichen werden mit dem "= = " - operator, auch nicht mit einer null
Da dieser code wird über ein Generisches API, das ist, was das Konzept fordert eine boxed Darstellung, die können
null
. Da jedoch eine solche hypothetische Sprache ändern würde, dass der compiler-Ausgabe ein Fehler hier (nicht den code knacken leise), kann ich mit der Tatsache Leben, dass es eventuell angepasst werden, für Java 10. Ich nehme an, dasStream
API wird ganz anders Aussehen, dann auch...InformationsquelleAutor Holger
Den folgenden code ersetzt
findFirst()
mitlimit(1)
und ersetztorElse()
mitreduce()
:limit()
erlaubt nur 1 element zu erreichenreduce
. DieBinaryOperator
übergebenreduce
gibt an, dass 1 element oder sonst"StringWhenListIsEmpty"
wenn keine Elemente erreichen diereduce
.Die Schönheit dieser Lösung ist, dass
Optional
ist nicht zugewiesen, und dieBinaryOperator
lambda ist nicht zu zuordnen, nichts.InformationsquelleAutor Nathan
Können Sie
java.util.Objects.nonNull
um die Liste zu filtern, bevor Sie findenetwas wie
firstString
zunull
wenn das erste Element instrings
istnull
.leider nutzt es
Optional.of
die nicht null ist sicher. Sie konntemap
zuOptional.ofNullable
und verwenden Sie dannfindFirst
aber Sie werden am Ende mit einem Optional OptionalInformationsquelleAutor Mattos
Optional soll es sich um einen "Wert" geben. (Lesen Sie das Kleingedruckte in javadoc🙂 JVM könnte sogar ersetzen alle
Optional<Foo>
mit nurFoo
entfernen boxing und unboxing Kosten. Einnull
Foo bedeutet eine leereOptional<Foo>
.Ist es möglich das design zu ermöglichen, Optional mit null-Wert, ohne ein boolean-flag - fügen Sie einfach eine sentinel-Objekt. (könnte sogar
this
als sentinel; siehe Throwable.Ursache)Die Entscheidung, die Optionalen können nicht wickeln null ist, nicht auf Laufzeit Kosten. Dies war ein sehr plead Frage, und Sie müssen zu Graben, die mailing-Listen. Die Entscheidung ist nicht überzeugend für alle.
In jedem Fall, da Optional nicht wickeln null Wert, es drängt uns in eine Ecke in Fällen wie
findFirst
. Sie müssen begründen, dass null-Werte sind sehr selten (es wurde auch berücksichtigt, dass der Stream sollte bar null-Werte), daher ist es bequemer zu werfen Ausnahme auf null-Werte statt auf leeren streams.Als workaround box
null
z.B.(Sie sagen, die Lösung für jedes OOP-problem ist die Einführung einer anderen Art 🙂
Box
geben. DieOptional
Typ selbst kann diesem Zweck dienen. Siehe meine Antwort für ein Beispiel.ja, aber das könnte verwirrend sein, da es nicht Zweck des Optional. In OP ' s Fall
null
ist ein Gültiger Wert, wie jede andere, keine Besondere Behandlung für Sie. (bis irgendwann später:)InformationsquelleAutor ZhongYu