在 Java 里,Stream 的filter
和 List 的removeIf
篩選效率要依據具體情形來判斷。
1. 操作本質有別
- Stream 的 filter:
- 它是一種中間操作,不會立刻執行,而是把篩選條件記錄下來。只有遇到終端操作時,才會開始處理元素。
- 此操作不會對原集合進行修改,而是生成一個新的流。
- List 的 removeIf:
- 這是一種終端操作,會立即對原集合進行修改,刪除滿足條件的元素。
- 它直接在原集合上進行元素的刪除操作。
2. 效率對比分情況
- 單次篩選場景:
當你只需要對集合進行一次篩選時,removeIf
的效率更高。這是因為它直接在原集合上進行操作,避免了創建新的流和中間集合。 - 鏈式操作場景:
如果需要進行多次篩選或者其他中間操作,Stream 的filter
會更高效。因為 Stream 采用延遲執行策略,能將多個操作進行優化合并,減少遍歷次數。
3. 示例與性能測試
下面通過代碼來直觀感受兩者的性能差異:
java
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class FilterVsRemoveIf {public static void main(String[] args) {// 創建一個包含大量元素的列表List<Integer> list = new ArrayList<>();for (int i = 0; i < 1000000; i++) {list.add(i);}// 測試Stream的filterlong startTime = System.currentTimeMillis();List<Integer> filteredList = list.stream().filter(e -> e % 2 == 0).collect(Collectors.toList());long endTime = System.currentTimeMillis();System.out.println("Stream filter耗時: " + (endTime - startTime) + "ms");// 重新創建相同的列表用于測試removeIflist = new ArrayList<>();for (int i = 0; i < 1000000; i++) {list.add(i);}// 測試List的removeIfstartTime = System.currentTimeMillis();list.removeIf(e -> e % 2 != 0);endTime = System.currentTimeMillis();System.out.println("List removeIf耗時: " + (endTime - startTime) + "ms");}
}
測試結果分析:
- Stream 的 filter:由于要創建流、中間集合以及進行終端操作,會帶來一些額外的開銷。
- List 的 removeIf:直接在原集合上進行操作,無需創建新的集合,所以速度更快。
4. 如何選擇
- 選擇 Stream 的 filter 的情況:
- 你不想對原集合進行修改。
- 需要進行鏈式操作,比如多次篩選、映射等。
- 希望代碼更加簡潔易讀。
- 選擇 List 的 removeIf 的情況:
- 你想直接修改原集合。
- 只需要進行一次篩選操作。
- 追求更高的性能。
綜上所述,在單次篩選且需要修改原集合時,removeIf
是更好的選擇;而在需要鏈式操作或者保留原集合的場景下,filter
更為合適。結合本人使用心得,當你使用當前處理器與其他處理器公用一個傳入變量時,使用流式處理,不要操作原對象;僅有當前處理器時,建議使用list自有方法,因為它速度更快。