鑑於我有一個流Stream<T> stream = list.stream().filter(some predicate)
其中列表是非常大的,它是更有效的檢查流是否是通過做非空:stream.count() > 0
或做:stream.findFirst().isPresent()
?Java 8 findFirst()。isPresent()比count()> 0更有效嗎?
回答
如果你想知道的是,是否有匹配,你應該使用
list.stream().anyMatch(some predicate)
,不僅因爲它是更有效,而且,因爲它是表達你的意圖正確的成語。
正如有人說,anyMatch
是短路,這意味着它會停在第一場比賽,而count
會,顧名思義,返回前數所有匹配。根據流的內容,這可能會產生巨大的性能差異。但要注意,就可以使count
同樣有效,通過使用 list.stream().filter(some predicate).limit(1).count() > 0
然後,它也將停止在第一次出現後,但是,正如所說,anyMatch
仍然表達,你有興趣是否存在的首選方式是任何匹配。事情的變化,當任務是找出是否有至少n
匹配。然後,.limit(n).count() > n-1
(或>= n
)成爲自然的成語。
注意findFirst()
與其他解決方案不同,因爲它的答案取決於排序。所以如果你只想知道是否有匹配,你應該使用findAny()
。不過,有一個理論上的差異,由於在返回的匹配值的要求相比,只是告訴是否有匹配,像anyMatch
確實,雖然目前是不同的只是一個Optional
實例的製作,因此,可以忽略不計。
但既然你對編程的API來編碼你的意圖,則不應使用find…
當你只是想知道是否有匹配。 anyMatch
明確表達了您的意圖,並且在未來的實施或更復雜的情況下可能會有更高的收益。
findAny
(如果你不需要排序而最好findFirst
)和anyMatch
是short-circuiting operations,這意味着它們可以在不消耗整個流,如果條件允許提前返回。這是在他們的方法javadocs中提到並鏈接的。 count()
is not。
如果流的最後階段仍然採用與SIZED特性的spliterator然後count()
可以是一樣快,其他兩個選項。但是這是一個比短路更弱的特性,因爲中間流操作(如filter()
)很可能會丟棄SIZED方面。
所有這些信息都可以從包裝文檔中找到,因此強烈推薦閱讀。
由於該問題的代碼合併了「過濾器」操作,因此無法測試每個元素以獲取匹配元素的數量。除了熱點優化器可能檢測到(在順序上下文中)計算計數不是必需的,因爲如何使用結果數字。無論哪種情況,「count」都是最差的賭注。 – Holger
@霍爾我沒有要求過。我只想提一提,在有限的情況下,「count」可能會一樣快。一個可以想象的優化就像是一個'.filter(Predictate.TRUE)'(如果存在的話)保存源分割器。 – the8472
我只是想提一下,可預見的大小可能出現的情況是衆所周知的(這就是爲什麼我把它從我的答案中排除,因爲它在這裏不適用),以及不存在總是「真實」謂詞,這可能不會那麼戲劇性,但更糟糕的是,在Oracle的JRE/OpenJDK中,直到Java 9 ... – Holger
- 1. EXISTS比COUNT(*)> 0更有效嗎?
- 2. COUNT(fld)比COUNT(*)更快嗎?
- 3. 的Java 8 parallelStream的FindFirst
- 4. Java 8可選的orElse,而isPresent
- 5. '==='比'!=='更高效嗎?
- 6. 是StringBuilder.Replace()比String.Replace更有效嗎?
- 7. 和數據時,COUNT(*)> 0
- 8. 在Java中8
- 9. regexec和regcomp比做strncmp更有效嗎?
- 10. BoundStatement比Cassandra中的SimpleStatement更有效嗎?
- 11. `sizeof(some_vector [0])`有效嗎?
- 12. windows PID = 0有效嗎?
- 13. 使用php數組count()比SQL row count更快嗎?
- 14. Java 8 Streams Count all Keys
- 15. SQL:使COUNT(*)> 1高效
- 16. 存在Java 8 lambda表達式
- 17. 比較float比double更高效嗎?
- 18. LINQ Count()直到,這樣更有效率嗎?
- 19. 爲什麼mysql count(*)比count更好(id)
- 20. MySQL的SELECT COUNT> 0的布爾值
- 21. mysql的SELECT COUNT其中計數> 0
- 22. Java併發JDK 1.6:繁忙等待比信令更好嗎?有效的Java#51
- 23. java httpsession有效嗎?
- 24. Java 8:比較不同類型列表的更有效的方法?
- 25. 有COUNT()= 0的困惑
- 26. 的java 8的FindFirst VS地圖上可選
- 27. 比較在Java 8
- 28. 使用x> = 0或x> -1更好嗎?
- 29. 比if語句更高效嗎?
- 30. erlang:now/0比os:timestamp/0更快?
它取決於它是哪個'List'實現,但它甚至沒有可比性,因爲它將您移動到流中。 – EJP
對於無限流,count()不會終止;即使對於有限的流,它也必須在返回之前遍歷整個流。而'findFirst()'或'findAny()'或'anyMatch(e - > true)'是短路的,它們在找到元素時會停止。 –
這裏真正的教訓是,正確的問題不在於效率,而在於正確性。使用findXxx或xxxMatch最好不是因爲它們更有效率,而是因爲它們更接近表達你想要了解的屬性。他們碰巧效率更高只是對圖書館提出了更好的查詢的一個令人愉快的副作用。 –