Gegeben ich habe einen Stream Stream<T> stream = list.stream().filter(some predicate)
wo die Liste sehr groß ist, ist es effizienter zu überprüfen, ob der Stream nicht leer ist, indem Sie: stream.count() > 0
oder indem Sie: stream.findFirst().isPresent()
?Ist Java 8 findFirst(). IsPresent() effizienter als count()> 0?
Antwort
Wenn alles, was Sie wissen wollen, ist, ob es eine Übereinstimmung gibt, sollen Sie
list.stream().anyMatch(some predicate)
, nicht nur weil es effizienter ist, sondern auch, weil es das richtige Idiom ist, dass Sie die Absicht zum Ausdruck.
von anderen Wie gesagt, anyMatch
Kurzschlüsse, die, dass es bedeutet, im ersten Spiel zu stoppen, während count
wird, wie der Name schon vor der Rückkehr, zählt alle Matches vermuten läßt. Abhängig vom Stream-Inhalt kann dies einen enormen Leistungsunterschied bewirken. Aber beachten Sie, dass Sie count
ähnlich effizient machen, durch die Verwendung list.stream().filter(some predicate).limit(1).count() > 0
Dann wird es auch nach dem ersten Auftreten zu stoppen, aber, wie gesagt, anyMatch
ist nach wie vor die bevorzugte Art und Weise zum Ausdruck bringt, dass Sie sich, ob es Interesse ist irgendein Spiel. Dinge ändern sich, wenn die Aufgabe ist herauszufinden, ob es mindestensn
Übereinstimmungen gibt. Dann wird .limit(n).count() > n-1
(oder >= n
) das natürliche Idiom.
Beachten Sie, dass findFirst()
sich von der anderen Lösung unterscheidet, da ihre Antwort von der Bestellung abhängt. Wenn Sie also nur wissen wollen, ob es eine Übereinstimmung gibt, sollten Sie stattdessen findAny()
verwenden. Dennoch gibt es einen theoretischen Unterschied aufgrund der Anforderung, den übereinstimmenden Wert zurückzugeben, verglichen damit, nur zu sagen, ob es eine Übereinstimmung gibt, wie anyMatch
, obwohl dieser Unterschied derzeit nur in der Konstruktion einer Optional
Instanz liegt, daher vernachlässigbar ist.
Aber da Sie gegen eine API programmieren, um Ihre Absicht zu kodieren, sollten Sie nicht find…
verwenden, wenn Sie nur wissen wollen, ob es eine Übereinstimmung gibt. anyMatch
drückt Ihre Absicht deutlich aus und könnte in zukünftigen Implementierungen oder komplexeren Szenarien einen noch höheren Nutzen haben.
Ich würde empfehlen, list.stream().anyMatch(some predicate)
, die eine Terminal-Operation für genau diesen Fall ist. Es ist nicht nur effizienter als stream.count()
, aber es wird nicht auf unendlichen Streams hängen.
good point of, an unendlichen strömen hängen! –
@Holger Es klingt, als ob du mit etwas nicht einverstanden bist, was ich gesagt habe. – shmosel
Vielleicht habe ich gestern in Ihrer Antwort etwas falsch verstanden, ich denke, ich habe das "nur" übersehen ... Ich habe nicht runtergestimmt, falls Sie sich fragen. – Holger
findAny
(die findFirst
vorzuziehen ist, wenn Sie benötigen Bestellung nicht) und anyMatch
sind short-circuiting operations, das heißt, sie können früh zurückzukehren, ohne den gesamten Strom aufwendig, wenn es die Bedingungen erlauben. Dies wird in ihrer Methode javadocs erwähnt und verknüpft. count()
is not. kann dann count()
so schnell sein wie die beiden anderen Optionen
Wenn die letzte Stufe der Strom noch eine spliterator mit dem SIZED Charakteristik verwendet. Dies ist jedoch eine viel schwächere Eigenschaft als ein Kurzschluss, da Zwischenstromprozesse - wie filter()
- sehr wahrscheinlich den SIZED-Aspekt verwerfen.
All diese Informationen können aus der Paketdokumentation entnommen werden, es wird dringend empfohlen, zu lesen.
Da der Code der Frage eine 'Filter'-Operation enthält, gibt es keine Möglichkeit, jedes Element zu testen, um die Anzahl der übereinstimmenden Elemente zu erhalten. Abgesehen davon, dass der Hotspot-Optimierer (in einem sequenziellen Kontext) erkennen könnte, dass die Berechnung der Anzahl nicht notwendig ist, da die resultierende Zahl verwendet wird. In jedem Fall ist "count" die schlechteste Wette. – Holger
@Holger Ich habe nicht anders behauptet. Ich wollte nur erwähnen, dass "Count" unter begrenzten Umständen genauso schnell sein kann. Eine denkbare Optimierung wäre etwas wie ein '.filter (Predictate.TRUE)' (wenn es existiert), das den Quell-Spliterator bewahrt. – the8472
Ich wollte nur erwähnen, dass die Umstände, unter denen eine vorhersehbare Größe verfügbar sein könnte, gut bekannt sind (weshalb ich es von meiner Antwort wegließ, da es hier nicht anwendbar ist), und ein Prädikat "immer" existiert nicht , die vielleicht nicht so dramatisch, aber noch schlimmer ist, in Oracles JRE/OpenJDK wird die bekannte Zahl von 'SIZED'-Spliteratoren erst verwendet, nachdem Java 9 ... – Holger
- 1. Java 8 Optional oderElse wobei isPresent
- 2. Java 8 findfirst vs Karte auf optional
- 3. 'Optional.get()' ohne 'isPresent()' überprüft
- 4. Wie Index von findfirst() in Java erhalten 8
- 5. Ist StringBuilder.Replace() effizienter als String.Replace?
- 6. Finden Sie den "meisten" richtigen Wert mit Java 8 Prädikat
- 7. Ist MySQL effizienter als ein Dateisystem?
- 8. effizienter als gsub zweimal
- 9. Welche davon ist in Java effizienter?
- 10. Vermeiden isPresent() und get() in der Steuerlogik
- 11. Sortieralgorithmen effizienter als Blasensortierung
- 12. Warum Enum.map ist effizienter als Enum.count in Elixir?
- 13. Efficiency of collection.stream(). Überspringen(). Findfirst()
- 14. FindFirst und Fragezeichen
- 15. In Bezug auf Speicher, ist "implementiert" effizienter als "erweitert"?
- 16. Entfalten mehrere optionale Variablen in Java 8
- 17. Warum ist list.size()> 0 langsamer als list.isEmpty() in Java?
- 18. Ist `(T *) 0 - (T *) 0 'gut definiert als 0?
- 19. Karte und FindFirst
- 20. Java 8 Iterator Stromfilter NoSuchElementException
- 21. Null-Überprüfung in Java konvertieren 8 Optional
- 22. Ist eine Unterbrechung effizienter als das Überprüfen der Schleifenbedingung in Java?
- 23. Java 8 und Java 8
- 24. was ist effizienter für sftp: Java oder Shell-Skript?
- 25. Ist diese Project Euler # 5 Lösung effizienter als eine bekannte?
- 26. Warum ist BuiltStatement in Cassandra effizienter als BoundStatement?
- 27. Was ist der Unterschied zwischen den isPresent und isDisplayed Methoden
- 28. Minimalwert wird immer als 0 in Java
- 29. Wie kann effizienter sein, mehr als Array.some
- 30. findFirst() für Java-Streams, aber für n Elemente?
Es hängt davon ab, welche 'List'-Implementierung es ist, aber es ist nicht einmal vergleichbar, da es Sie im Stream bewegt. – EJP
Bei unendlichen Streams endet 'count()' nicht einmal; selbst für endliche Ströme muss es den gesamten Strom durchlaufen, bevor es zurückkehrt. Während 'findFirst()' oder 'findAny()' oder 'anyMatch (e -> true)' kurzgeschlossen sind, hören sie auf, wenn sie ein Element finden. –
Die wahre Lektion hier ist, dass die richtige Frage nicht die Effizienz, sondern die Korrektheit ist. Die Verwendung von 'findXxx' oder' xxxMatch' ist besser, nicht weil sie effizienter sind, sondern weil sie näher an der Eigenschaft sind, die Sie eigentlich kennen möchten. Dass sie effizienter sind, ist lediglich ein angenehmer Nebeneffekt der besseren Abfrage der Bibliothek. –