1. Stream 操作分類
Stream 操作分為兩類:
中間操作(Intermediate Operations)
返回新的?
Stream
,可以鏈式調用(如?filter
,?map
,?sorted
,?distinct
)。惰性求值:只有遇到終止操作時才會執行。
終止操作(Terminal Operations)
返回非?
Stream
?結果(如?collect
,?count
,?sum
,?forEach
)。觸發計算,執行所有中間操作。
2. 常用 Stream 操作
(1) 過濾:filter(Predicate<T>)
作用:篩選符合條件的元素。
示例:篩選以?"a"
?開頭的字符串。
java
List<String> list = List.of("apple", "banana", "avocado", "orange"); List<String> filtered = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList()); // 結果:["apple", "avocado"]
(2) 映射:map(Function<T, R>)
作用:將元素轉換為另一種形式(如大小寫轉換、提取字段)。
示例:所有字符串轉為大寫。
java
List<String> upper = list.stream().map(String::toUpperCase).collect(Collectors.toList()); // 結果:["APPLE", "BANANA", "AVOCADO", "ORANGE"]
提取對象屬性:
java
List<Person> people = ...; List<String> names = people.stream().map(Person::getName).collect(Collectors.toList());
(3) 排序:sorted()
?/?sorted(Comparator<T>)
作用:按自然順序或自定義比較器排序。
示例:按字母順序排序。
java
List<String> sorted = list.stream().sorted().collect(Collectors.toList()); // 結果:["apple", "avocado", "banana", "orange"]
自定義排序(按字符串長度):
java
List<String> sortedByLength = list.stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList()); // 結果:["apple", "banana", "orange", "avocado"]
(4) 去重:distinct()
作用:去除重復元素(依賴?equals()
?和?hashCode()
)。
示例:
java
List<String> withDuplicates = List.of("a", "b", "a", "c"); List<String> distinct = withDuplicates.stream().distinct().collect(Collectors.toList()); // 結果:["a", "b", "c"]
(5) 聚合操作
計數:count()
java
long count = list.stream().count(); // 4
求和:mapToInt()
?+?sum()
java
List<String> numbers = List.of("1", "2", "3"); int sum = numbers.stream().mapToInt(Integer::parseInt).sum(); // 6
求最大值/最小值
java
Optional<String> max = list.stream().max(Comparator.naturalOrder()); Optional<String> min = list.stream().min(Comparator.comparing(String::length));
匹配檢查
anyMatch(Predicate<T>)
(任一元素匹配)allMatch(Predicate<T>)
(所有元素匹配)noneMatch(Predicate<T>)
(無元素匹配)
java
boolean hasA = list.stream().anyMatch(s -> s.contains("a")); // true
3. 終止操作:collect(Collectors.toList())
collect()
?是常用的終止操作,用于將流轉換為集合或其他數據結構。
常見?Collectors
?方法:
方法 | 作用 |
---|---|
Collectors.toList() | 轉為?List |
Collectors.toSet() | 轉為?Set (自動去重) |
Collectors.joining(delimiter) | 拼接字符串 |
Collectors.groupingBy(Function) | 按條件分組 |
Collectors.partitioningBy(Predicate) | 按條件分區(true/false) |
示例:
java
// 拼接字符串 String joined = list.stream().collect(Collectors.joining(", ")); // 結果:"apple, banana, avocado, orange"// 分組(按首字母) Map<Character, List<String>> grouped = list.stream().collect(Collectors.groupingBy(s -> s.charAt(0))); // 結果:{'a': ["apple", "avocado"], 'b': ["banana"], 'o': ["orange"]}
4. 并行流(Parallel Stream)
通過?parallelStream()
?利用多核 CPU 加速計算(適合大數據量)。
示例:
java
List<String> parallelProcessed = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
注意:
并行流不保證順序。
小數據量可能更慢(線程開銷)。
5. 完整示例
java
List<String> fruits = List.of("apple", "banana", "avocado", "orange", "apple");// 過濾 + 映射 + 去重 + 排序 List<String> result = fruits.stream().filter(s -> s.length() > 5) // 篩選長度 >5.map(String::toUpperCase) // 轉大寫.distinct() // 去重.sorted() // 排序.collect(Collectors.toList()); // 轉為 List// 結果:["AVOCADO", "BANANA", "ORANGE"]
6. 總結
操作 | 方法 | 示例 |
---|---|---|
過濾 | filter(Predicate) | .filter(s -> s.startsWith("a")) |
映射 | map(Function) | .map(String::toUpperCase) |
排序 | sorted() | .sorted(Comparator.reverseOrder()) |
去重 | distinct() | .distinct() |
聚合 | count() ,?sum() | .mapToInt(Integer::parseInt).sum() |
收集 | collect(Collectors.toList()) | .collect(Collectors.joining(", ")) |
適用場景:
需要對集合進行復雜處理(如過濾、轉換、分組)。
代碼可讀性比性能更重要(小數據量)。
并行流適合大數據計算(如日志分析、批量處理)。
傳統循環 vs Stream:
java
// 傳統方式(繁瑣) List<String> filtered = new ArrayList<>(); for (String s : list) {if (s.startsWith("a")) {filtered.add(s.toUpperCase());} }// Stream 方式(簡潔) List<String> filtered = list.stream().filter(s -> s.startsWith("a")).map(String::toUpperCase).collect(Collectors.toList());
Stream API 讓代碼更符合?“做什么”?而非?“怎么做”?的編程風格,推薦在 Java 8+ 項目中廣泛使用!