Ist Java 8 findFirst (). isPresent () effizienter als count () 0?

8

Da ich einen Stream Stream<T> stream = list.stream().filter(some predicate) habe, bei dem die Liste sehr groß ist, ist es effizienter zu überprüfen, ob der Stream nicht leer ist: stream.count() > 0 oder: stream.findFirst().isPresent() ?

    
Siddhu 26.09.2016, 23:41
quelle

3 Antworten

5

Wenn du nur wissen willst, ob es eine Übereinstimmung gibt, solltest du list.stream().anyMatch(some predicate) verwenden, nicht nur, weil es effizienter ist, sondern auch, weil es das richtige Idiom ist, um deine Absicht auszudrücken.

Wie von anderen gesagt, ist anyMatch kurzgeschlossen, was bedeutet, dass es bei der ersten Übereinstimmung stoppt, während count , wie der Name schon sagt, alle Treffer zählt, bevor es zurückkehrt . Abhängig vom Stream-Inhalt kann dies einen enormen Leistungsunterschied bewirken. Beachten Sie jedoch, dass Sie count ähnlich effizient machen können, indem Sie list.stream().filter(some predicate).limit(1).count() > 0

Dann wird es auch nach dem ersten Auftreten anhalten, aber wie gesagt, anyMatch ist immer noch der bevorzugte Weg, um auszudrücken, dass Sie daran interessiert sind, ob es irgendeine Übereinstimmung gibt. Die Dinge ändern sich, wenn die Aufgabe darin besteht, herauszufinden, ob mindestens n übereinstimmt. Dann wird .limit(n).count() > n-1 (oder >= n ) zum natürlichen Idiom.

Beachten Sie, dass sich findFirst() von der anderen Lösung unterscheidet, da ihre Antwort von der Reihenfolge abhängt. Wenn Sie also nur wissen möchten, 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 ist vernachlässigbar.

Da Sie jedoch mit einer API programmieren, um Ihre Absicht zu verschlüsseln, sollten Sie find… nicht verwenden, wenn Sie nur wissen möchten, ob eine Übereinstimmung besteht. anyMatch drückt Ihre Absicht deutlich aus und könnte in zukünftigen Implementierungen oder komplexeren Szenarien einen noch höheren Nutzen haben.

    
Holger 27.09.2016, 10:09
quelle
11

Ich würde empfehlen, list.stream().anyMatch(some predicate) zu verwenden, was genau für diesen Fall eine Terminaloperation ist. Es ist nicht nur effizienter als stream.count() , es hängt auch nicht an unendlichen Streams.

    
shmosel 26.09.2016 23:49
quelle
2

findAny (was besser ist als findFirst , wenn Sie keine Bestellung benötigen) und anyMatch sind Kurzzirkeloperationen , was bedeutet, dass sie früher zurückkehren können, ohne den gesamten Stream zu verbrauchen, wenn die Bedingungen es zulassen. Dies wird in der Methode Javadocs . count() ist nicht .

Wenn die letzte Phase des Streams noch einen Spliterator mit der GRÖßE Merkmal dann count() kann so schnell sein wie die anderen beiden Optionen. 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 der Paketdokumentation entnommen werden, es wird dringend empfohlen, sie zu lesen.

    
the8472 27.09.2016 16:01
quelle

Tags und Links