Java enthält vs anyMatch Verhalten
Also wenn ich einen Name
Objekt und haben eine ArrayList
Typ Name
(names
), und ich möchte prüfen, ob meine Liste von Namen enthält, die einem bestimmten Name
Objekt (n
), konnte ich es zwei Möglichkeiten:
boolean exists = names.contains(n);
oder
boolean exists - names.stream().anyMatch(x -> x.equals(n));
Ich überlegte, ob diese beiden Verhalten und dann überlegt, was passiert, wenn n zugewiesen wurde null
?
Für enthält, so wie ich das verstehe, ist das argument null
, dann kehrt er zurück true
enthält die Liste null
. Wie würde ich dies erreichen anyMatch
- würde es durch die Verwendung Objects.equals(x, n)
?
Wenn das funktioniert, dann, welche Vorgehensweise effizienter ist - ist es anyMatch
wie kann es von Vorteil Faulheit und Parallelität?
names
geben?Wenn
names
ist in der Tat ein ArrayList
, dann würde ich sagen die Leistung wäre ähnlich. Aber wenn es so etwas wie eine HashSet
dann ein contains
nennen, wäre fast sicher effizienter (da es nicht wirklich brauchen, um eine Schleife durch die Elemente).Er Sprach, dass es eine
ArrayList
. Es ist zumindest davon auszugehen, dass dies wahr ist.Ich bin nicht zu hinterfragen, nur gibt ein wenig mehr Informationen als verlangt. Die Beantwortung der spezifischen engen Frage allein würde vielleicht geben ein Falsches Bild.
Vereinbart ist, könnte es sich lohnen, zeigen diese Differenz (als Zbynek Vyskovsky - kvr000 auch schon in seiner Antwort)
InformationsquelleAutor Tranquility | 2016-02-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem mit den stream-basierten version ist, dass wenn der Sammlung (und damit seine stream) enthält
null
Elemente, dann das Prädikat werfen wirdNullPointerException
wenn er versucht zu rufenequals
auf diesernull
Objekt.Dies könnte vermieden werden, mit
Aber es gibt keinen praktischen Vorteil zu erwarten, für die stream-basierte Lösung in diesem Fall. Parallelität bringen könnte ein Vorteil für wirklich große Listen, aber man sollte nicht beiläufig werfen in einigen
parallel()
hier und da unter der Annahme, dass es kann machen Dinge schneller. Zunächst sollten Sie eindeutig identifizieren die tatsächliche Engpässe.Und in Bezug auf Lesbarkeit, würde ich es vorziehen, die ersten, die klassische Lösung hier. Wenn Sie möchten, um zu überprüfen, ob die Liste der
names.contains(aParticularValue)
Sie sollte dies tun - es liest sich wie Prosa, und macht die Absicht deutlich.Weiterer Vorteil des
contains
Ansatz wurde erwähnt in den Kommentaren und in der anderen Antwort, und das kann sich lohnen, hier zu erwähnen: Wenn der Typ desnames
Sammlung ist später verändert werden, zum Beispiel einHashSet
, dann bekommst du den schnellercontains
-check (mit O(1) statt O(n)) für frei, ohne jeden anderen Teil des Codes. Die stream-basierte Lösung wäre dann noch zu Durchlaufen alle Elemente, und dies hätte eine deutlich geringere Leistung.LinkedHashSet
oder ähnlich, wenn die Reihenfolge beibehalten werden muss).InformationsquelleAutor Marco13
Sollten Sie liefern das gleiche Ergebnis, wenn
hashCode()
undequals()
geschrieben sind, in angemessener Weise.Aber die Leistung kann völlig unterschiedlich sein. Für Listen, es würde keine Rolle, dass viel, aber für HashSet
contains()
verwendenhashCode()
um das element zu suchen und es fertig sein wird (wahrscheinlich) in konstanter Zeit. Während bei der zweiten Lösung wird über alle Elemente iterieren und eine Funktion aufrufen, so erfolgt in linearer Zeit.Wenn n null ist, ist eigentlich egal, da in der Regel
equals()
Methoden sind bewusstnull
Argumente.equals
Methode soll überprüfen, ob seine argument istnull
. Aber hier das Prädikat versuchen könnten, rufen Sie dieequals
Methode auf einenull
Objekt, was zu einer NPEInformationsquelleAutor Zbynek Vyskovsky - kvr000