趕緊收藏!Java Stream 的使用技巧
Java Stream API 就像 Java 開發人員最常用的武器,它用途廣泛、結構緊湊,可以輕松處理各種任務。
它為開發人員提供了一種功能性和聲明性的方式來表達復雜的數據轉換和操作,使代碼更加簡潔、更具表現力。
但是,能力越大責任越大,有效使用流 API 需要對最佳實踐和常見陷阱有扎實的了解。
今天,我們將探討使用 Java Stream API 的一些最佳實踐,并向您展示如何充分釋放這一神奇工具的潛力。
無論您是初學者還是經驗豐富的開發人員,您都一定能在使用 Java 流的過程中學到一些令人興奮的新知識。
使用原始數據流,提高性能
在處理 int、long 和 double 等基本類型時,應使用 IntStream、LongStream 和 DoubleStream 等基元流,而不是 Integer、Long 和 Double 等盒裝類型流。原始數據流可以避免裝箱和拆箱的代價,從而提供更好的性能。
var array = new int[]{1, 2, 3, 4, 5};
var sum = Arrays.stream(array)
.sum();
避免嵌套流
最佳實踐是避免嵌套流,因為它可能導致代碼難以閱讀和理解。相反,嘗試將問題分解為更小的部分,并使用中間集合或局部變量來存儲中間結果。
var list1 = Arrays.asList("apple", "banana", "cherry");
var list2 = Arrays.asList("orange", "pineapple", "mango");
var result = Stream.concat(list1.stream(), list2.stream())
.filter(s -> s.length() > 5)
.collect(Collectors.toList());
謹慎使用并行流
并行流可以在處理大量數據時提供更好的性能,但它們也會引入開銷和競爭條件。謹慎使用并行流,并考慮數據大小、操作復雜性和可用處理器數量等因素。
var list = Arrays.asList(1, 2, 3, 4, 5);
var sum = list.parallelStream().reduce(0, Integer::sum);
使用惰性求值以獲得更好的性能
Stream API 支持延遲計算,這意味著在調用終端操作之前不會執行中間操作。作為最佳實踐,嘗試使用惰性計算來通過減少不必要的計算來提高性能。
var list = Arrays.asList(1, 2, 3, 4, 5);
var result = list.stream()
.filter(n -> n > 3)
.findFirst();
避免副作用
Stream API 旨在對數據執行功能操作。避免引入副作用,例如修改流外部的變量或執行 I/O 操作,因為這可能會導致不可預測的行為并降低代碼可讀性。
var list = Arrays.asList("apple", "banana", "cherry");
var count = 0;
list.stream()
.filter(s -> s.startsWith("a"))
.forEach(s -> count++);
//將流與不可變對象一起使用:Stream API 最適合與不可變對象一起使用。
//使用不可變對象可確保流的狀態在處理過程中不會被修改,這可以帶來更可預測的行為和更好的代碼可讀性。
var list = Arrays.asList("apple", "banana", "cherry");
var result = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
將流與不可變對象一起使用
Stream API 最適合不可變對象。使用不可變對象可確保流的狀態在處理過程中不會被修改,這可以帶來更可預測的行為和更好的代碼可讀性。
var list = Arrays.asList("apple", "banana", "cherry");
var result = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
在map()之前使用filter()以避免不必要的處理
如果您的流可能包含大量不符合您的條件的元素,請在 map() 之前使用 filter() 以避免不必要的處理。這可以提高代碼的性能。
var list = Arrays.asList(1, 2, 3, 4, 5);
var filteredList = list.stream()
.filter(i -> i % 2 == 0)
.map(i -> i * 2)
.collect(Collectors.toList());
優先選擇方法引用而不是 lambda 表達式
與使用 lambda 表達式相比,方法引用可以使您的代碼更加簡潔和可讀。如果可以使用方法引用代替 lambda 表達式,那么更喜歡它。
var list = Arrays.asList(1, 2, 3, 4, 5);
var sum = list.stream()
.reduce(0, Integer::sum);
使用distinct()刪除重復項
如果您的數據流可能包含重復元素,那么使用distinct() 方法來去重,刪除它們
var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
.distinct()
.collect(Collectors.toList());
謹慎使用sorted()
Sorted() 操作可能會開銷很大,尤其是對于數據量很大的流。不到萬不得已請不要使用。如果您知道輸入數據已經排序,則可以跳過此操作。
var list = Arrays.asList(3, 2, 1);
var sortedList = list.stream()
.sorted()
.collect(Collectors.toList());
Java Stream API 很強大而且很靈活,用得好能夠顯著簡化數據處理任務的代碼,大大提高我們的開發效率。同時也是一把雙刃劍,盡量保證避開一些坑。