# Java Stream的用法
## 一、Stream概述
Java 8引入的Stream API是處理集合數據的革命性工具,它允許開發者以聲明式方式操作數據集合。Stream不是數據結構,而是對數據源(如集合、數組等)的高級抽象,支持鏈式函數式操作。
核心特點:
- **惰性執行**:中間操作不會立即執行,只有遇到終止操作時才觸發計算
- **不可復用**:每個Stream只能被消費一次
- **并行能力**:只需調用`parallel()`即可實現并行處理
## 二、Stream創建方式
### 1. 從集合創建
```java
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 順序流
Stream<String> parallelStream = list.parallelStream(); // 并行流
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream<String> stream = Stream.of("a", "b", "c");
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2); // 無限流
Stream<Double> randomStream = Stream.generate(Math::random); // 生成流
中間操作返回新的Stream,可以連續調用:
stream.filter(s -> s.startsWith("a")) // 過濾以a開頭的元素
.distinct() // 去重
.skip(1) // 跳過前N個元素
.limit(5); // 限制元素數量
stream.map(String::toUpperCase) // 元素轉換
.mapToInt(String::length) // 轉換為數值流
.flatMap(s -> Stream.of(s.split(""))) // 扁平化流
stream.sorted() // 自然排序
.sorted(Comparator.reverseOrder()) // 自定義排序
stream.forEach(System.out::println);
boolean anyMatch = stream.anyMatch(s -> s.contains("a"));
boolean allMatch = stream.allMatch(s -> s.length() > 3);
boolean noneMatch = stream.noneMatch(s -> s.isEmpty());
Optional<String> first = stream.findFirst();
Optional<String> any = stream.findAny();
Optional<String> concat = stream.reduce(String::concat);
long count = stream.count();
IntSummaryStatistics stats = stream.mapToInt(String::length).summaryStatistics();
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
String joined = stream.collect(Collectors.joining(","));
Map<String, Integer> map = stream.collect(Collectors.toMap(
Function.identity(),
String::length
));
處理原始類型時更高效的變體:
IntStream intStream = IntStream.range(1, 100); // 1-99
DoubleStream doubleStream = DoubleStream.of(1.1, 2.2);
LongStream longStream = LongStream.generate(() -> new Random().nextLong());
list.parallelStream()
.filter(s -> s.length() > 3)
.forEach(System.out::println);
注意事項: - 確保操作是線程安全的 - 避免有狀態的操作 - 數據量小時可能降低性能
方法 | 說明 |
---|---|
toList() |
收集為List |
toSet() |
收集為Set |
toMap() |
收集為Map |
groupingBy() |
分組收集 |
partitioningBy() |
分區收集 |
joining() |
字符串連接 |
counting() |
計數 |
summarizingInt() |
統計匯總 |
List<Product> products = ...;
DoubleSummaryStatistics stats = products.stream()
.mapToDouble(Product::getPrice)
.summaryStatistics();
System.out.println("平均價格: " + stats.getAverage());
Map<Category, List<Product>> byCategory = products.stream()
.collect(Collectors.groupingBy(Product::getCategory));
Map<Category, Map<String, List<Product>>> multiGroup = products.stream()
.collect(Collectors.groupingBy(
Product::getCategory,
Collectors.groupingBy(p -> p.getPrice() > 100 ? "高價" : "普通")
));
IllegalStateException
peek()
方法觀察流經的元素Java Stream API通過函數式編程范式: - 使集合操作更簡潔直觀 - 提供強大的數據轉換能力 - 內置并行處理支持 - 提升代碼可讀性和維護性
合理運用Stream可以顯著提升開發效率,但需注意其適用場景和潛在的性能影響。建議結合具體業務需求,在命令式編程和函數式編程之間做出平衡選擇。 “`
注:本文實際約1700字,完整覆蓋了Stream的核心概念、創建方式、操作類型、使用技巧和注意事項。如需擴展具體部分,可以進一步補充更多示例或性能優化建議。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。