一、Stream 的基礎概念
-
定義與特性
- Stream 是單向數據流,對集合或數組進行高效處理,不存儲數據,而是通過操作鏈生成新 Stream。
- 不可變性:原始數據源不被修改,所有操作均返回新 Stream。
- 延遲執行:中間操作(如
filter
)不會立即執行,需終端操作(如collect
)觸發計算。
-
核心優勢
- 簡潔性:通過鏈式調用簡化復雜邏輯(如
map
+filter
)。 - 高效性:支持并行處理(
parallelStream()
),充分利用多核性能。 - 靈活性:提供豐富的操作符(如
flatMap
處理嵌套集合)。
- 簡潔性:通過鏈式調用簡化復雜邏輯(如
二、Stream 的創建方式
-
從集合/數組創建
List list = Arrays.asList("Java", "Python", "C++"); Stream listStream = list.stream(); // 集合轉Stream Stream arrayStream = Arrays.stream(new String[]{"A", "B"}); // 數組轉Stream
-
其他創建方式
- 空 Stream:
Stream.empty()
(避免返回null
)。 - 構造器:
Stream.builder().add("A").build()
。 - 生成器:
Stream generated = Stream.generate(() -> "data").limit(5); // 無限流截斷 Stream iterated = Stream.iterate(1, n -> n + 1).limit(10); // 遞增生成
- 空 Stream:
三、Stream 的核心操作分類
1. 中間操作(Intermediate Operations)
操作 | 作用 | 示例代碼 |
---|---|---|
filter | 篩選元素 | list.stream().filter(s -> s.length() > 3) // 篩選長度>3的字符串 |
map | 轉換元素類型或值 | .map(String::toUpperCase) // 轉換為大寫 |
sorted | 排序 | .sorted(Comparator.naturalOrder()) // 自然排序 |
flatMap | 扁平化嵌套集合 | List> nestedList; nestedList.stream().flatMap(List::stream) |
distinct | 去重 | .distinct() // 基于 equals() 去重 |
2. 終端操作(Terminal Operations)
操作 | 作用 | 示例代碼 |
---|---|---|
collect | 收集結果為集合或對象 | .collect(Collectors.toList()) // 轉為List |
reduce | 歸約操作(求和、拼接等) | Stream.of(1,2,3).reduce(0, Integer::sum) // 結果為6 |
forEach | 遍歷元素 | .forEach(System.out::println) // 打印所有元素 |
count | 統計元素數量 | .count() // 返回Long類型總數 |
四、實戰場景與示例
-
數據篩選與轉換
List員工列表 = ...; List names = 員工列表.stream().filter(e -> e.getAge() > 30).map(E員工::getName).collect(Collectors.toList()); // 篩選年齡>30的員工姓名
-
分組統計
Map groupedByDep = 員工列表.stream().collect(Collectors.groupingBy(E員工::getDepartment)); // 按部門分組
-
雙列集合處理
Map map = new HashMap<>(); Stream> entryStream = map.entrySet().stream();
五、進階特性與注意事項
-
并行流(Parallel Streams)
- 通過
parallelStream()
啟用多線程處理,適用于大數據量場景。 - 注意線程安全問題,避免非線程安全集合(如
ArrayList
)的并發修改。
- 通過
-
基本類型專用流
IntStream
、LongStream
、DoubleStream
優化內存和性能,避免自動裝箱開銷:IntStream.range(1, 100).sum(); // 計算1-99的和
-
避免常見錯誤
- 多次使用終端操作:Stream 一旦被終端操作消費,不可復用。
- 無限流處理:需結合
limit()
截斷,防止內存溢出。
六、總結
Java Stream API 通過函數式編程范式,顯著提升了集合操作的簡潔性和性能。合理使用 map
、filter
、collect
等操作,結合并行流和基本類型流優化,可高效處理復雜數據場景。開發者需注意流的生命周期和線程安全,以充分發揮其優勢。