Java 8 引入的 Stream API 是一個強大的工具,用于處理集合(如 List、Set)中的元素。它支持各種操作,包括過濾、排序、映射等,并且能夠以聲明式的方式表達復雜的查詢操作。流操作可以是中間操作(返回流以便進一步處理)或終端操作(產生結果或副作用)。此外,Stream API 還支持并行執行,從而利用多核處理器的優勢。
Stream 的基本概念
-
源
任何提供數據的集合(如?List
、Set
、數組等)均可作為流的來源。 -
中間操作
返回新流對象,支持鏈式調用,惰性求值。常見操作包括:filter
(篩選)map
(映射)sorted
(排序)distinct
(去重)limit
(限制數量)skip
(跳過元素)flatMap
(扁平化映射)peek
(調試查看)
-
終端操作
觸發流處理并生成結果,執行后流被消耗。常見操作包括:forEach
(遍歷)collect
(收集到集合)reduce
(聚合)count
(統計數量)findFirst
/findAny
(查找元素)anyMatch
/allMatch
/noneMatch
(匹配驗證)
創建 Stream 的方式
-
從集合創建
List<String> list = Arrays.asList("apple", "banana", "pear"); Stream<String> stream = list.stream();
-
從數組創建
String[] arr = {"apple", "banana", "pear"}; Stream<String> stream = Arrays.stream(arr);
-
生成無限流
// 迭代生成(0, 1, 2, ...) Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);// 隨機生成 Stream<Double> randomStream = Stream.generate(Math::random);
中間操作詳解
1. 篩選與切片
-
filter
:按條件篩選元素List<String> filtered = list.stream().filter(s -> s.length() > 3).collect(Collectors.toList());
-
distinct
:去重(需重寫?equals
?和?hashCode
)List<Integer> distinctList = Arrays.asList(1, 2, 2, 3).stream().distinct().collect(Collectors.toList()); // [1, 2, 3]
-
limit
:截取前 N 個元素List<String> firstTwo = list.stream().limit(2).collect(Collectors.toList());
-
skip
:跳過前 N 個元素List<String> skipped = list.stream().skip(1).collect(Collectors.toList());
2. 映射與扁平化
-
map
:元素類型轉換List<String> upperCase = list.stream().map(String::toUpperCase).collect(Collectors.toList());
-
flatMap
:扁平化嵌套集合List<List<Integer>> nestedList = Arrays.asList(Arrays.asList(1, 2),Arrays.asList(3, 4) ); List<Integer> flatList = nestedList.stream().flatMap(List::stream).collect(Collectors.toList()); // [1, 2, 3, 4]
3. 排序
-
自然排序
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
-
自定義排序
List<Employee> sortedEmployees = employees.stream().sorted((e1, e2) -> e2.getAge() - e1.getAge()).collect(Collectors.toList());
4. 調試查看
peek
:遍歷元素時執行操作(如打印)list.stream().peek(System.out::println).collect(Collectors.toList());
終端操作詳解
1. 收集結果
-
收集到集合
List<String> listResult = Stream.of("a", "b", "c").collect(Collectors.toList());Set<String> setResult = Stream.of("apple", "banana", "pear").collect(Collectors.toSet());
-
分組與分區
Map<Integer, List<String>> grouped = list.stream().collect(Collectors.groupingBy(s -> s.length()));
2. 聚合操作
-
reduce
?求和int sum = numbers.stream().reduce(0, (a, b) -> a + b);
-
拼接字符串
String joined = Stream.of("a", "b", "c").reduce("", (a, b) -> a + b); // "abc"
-
無初始值的聚合
Optional<Integer> max = numbers.stream().reduce(Integer::max);
3. 查找與匹配
-
findFirst
:獲取第一個元素Optional<String> first = list.stream().filter(s -> s.startsWith("a")).findFirst();
-
findAny
:獲取任意元素(并行流中可能亂序)Optional<String> any = list.parallelStream().findAny();
-
max
/min
:獲取極值Optional<Integer> maxNumber = numbers.stream().max(Integer::compare);
4. 匹配驗證
-
anyMatch
:至少一個元素滿足條件boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
-
allMatch
:所有元素滿足條件boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
-
noneMatch
:無元素滿足條件boolean noEven = numbers.stream().noneMatch(n -> n % 2 == 0);
5. 統計與轉換
-
count
:統計元素數量long count = list.stream().filter(s -> s.length() > 3).count();
-
toArray
:轉換為數組String[] array = list.stream().toArray(String[]::new);
-
數值統計
IntSummaryStatistics stats = numbers.stream().mapToInt(Integer::intValue).summaryStatistics(); System.out.println(stats.getAverage()); // 平均值
6. 遍歷操作
forEach
:執行副作用操作list.stream().forEach(System.out::println);
并行流(Parallel Stream)
-
啟用并行流
List<String> list = Arrays.asList("apple", "banana", "pear"); list.parallelStream().forEach(System.out::println);
-
注意事項
- 并行流可能提高大數據集處理性能。
- 需確保線程安全性(如避免共享狀態修改)。
- 并行排序(
sorted()
)可能不穩定,需謹慎使用。
注意事項
-
中間操作順序
邏輯順序需合理(如先?filter
?再?map
)。 -
對象去重
使用?distinct()
?時需重寫?hashCode()
?和?equals()
。 -
流復用問題
終端操作后流被消耗,需重新創建流:Stream<String> stream = list.stream(); stream.forEach(System.out::println); // 首次使用 stream.forEach(System.out::println); // 報錯!流已關閉
-
安全獲取值
使用?Optional
?的?orElse()
、orElseGet()
?或?orElseThrow()
?避免空指針。
總結
Java 8 Stream API 通過聲明式編程簡化了集合操作,支持鏈式調用和并行處理。合理使用中間操作(如?filter
、map
)和終端操作(如?collect
、reduce
),可高效完成數據聚合、過濾及驗證。結合并行流可顯著提升大數據集處理性能,但需注意線程安全性和操作順序。