# 如何使用Java 8新特性Stream
## 目錄
1. [Stream簡介](#stream簡介)
2. [Stream與集合的區別](#stream與集合的區別)
3. [Stream操作分類](#stream操作分類)
4. [創建Stream](#創建stream)
5. [中間操作](#中間操作)
- [篩選與切片](#篩選與切片)
- [映射](#映射)
- [排序](#排序)
6. [終止操作](#終止操作)
- [匹配與查找](#匹配與查找)
- [歸約](#歸約)
- [收集](#收集)
7. [并行Stream](#并行stream)
8. [實際應用場景](#實際應用場景)
9. [性能考量](#性能考量)
10. [常見問題與陷阱](#常見問題與陷阱)
11. [總結](#總結)
---
## Stream簡介
Java 8引入的Stream API是處理集合數據的革命性方式,它允許開發者以聲明式風格處理數據集合。Stream不是數據結構,而是對數據源(如集合、數組等)的高級抽象,支持順序和并行聚合操作。
核心特點:
- **聲明式編程**:只需說明"做什么"而非"如何做"
- **可組合性**:支持鏈式操作形成復雜的數據處理流水線
- **內部迭代**:迭代過程由庫內部處理
- **延遲執行**:中間操作不會立即執行
- **并行友好**:只需調用`parallel()`即可獲得并行處理能力
```java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.filter(name -> name.length() > 3)
.count();
特性 | 集合(Collection) | Stream |
---|---|---|
存儲 | 存儲所有元素 | 不存儲元素 |
數據結構 | 具體的數據結構 | 抽象的數據操作 |
操作方式 | 外部迭代(顯式迭代) | 內部迭代(隱式迭代) |
延遲加載 | 不支持 | 支持 |
可重用性 | 可多次使用 | 單次使用 |
并行處理 | 需要手動實現 | 內置支持 |
Stream操作分為兩類:
1. 中間操作(Intermediate Operations)
- 總是惰性的,返回新的Stream
- 例如:filter()
, map()
, sorted()
forEach()
, collect()
, reduce()
操作流水線示例:
list.stream() // 創建流
.filter(x -> x > 10) // 中間操作
.map(String::valueOf) // 中間操作
.collect(toList()); // 終止操作
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
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<String> emptyStream = Stream.empty();
// 基本類型流
IntStream intStream = IntStream.range(1, 10);
stream.filter(x -> x > 5)
stream.distinct()
stream.limit(3)
stream.skip(2)
names.stream().map(String::toUpperCase)
List<List<String>> listOfLists = ...;
listOfLists.stream()
.flatMap(List::stream)
stream.mapToInt(String::length)
stream.sorted()
stream.sorted(Comparator.reverseOrder())
boolean hasAdult = people.stream()
.anyMatch(p -> p.getAge() >= 18);
Optional<String> first = stream.findFirst();
long count = stream.count();
Optional<Integer> max = stream.max(Integer::compare);
int sum = numbers.stream()
.reduce(0, Integer::sum);
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
Collectors工具類常用方法:
.collect(Collectors.toList())
.collect(Collectors.toMap(k -> k, v -> v))
.collect(Collectors.groupingBy(Employee::getDepartment))
.collect(Collectors.partitioningBy(e -> e.getSalary() > 5000))
.collect(Collectors.joining(", "))
通過并行流利用多核處理器:
long count = list.parallelStream()
.filter(...)
.count();
注意事項: - 確保操作是線程安全的 - 避免有狀態的操作 - 考慮并行開銷(數據量小時可能更慢)
性能測試示例:
// 順序流
long start = System.nanoTime();
list.stream().sorted().count();
long seqTime = System.nanoTime() - start;
// 并行流
start = System.nanoTime();
list.parallelStream().sorted().count();
long paraTime = System.nanoTime() - start;
List<Product> expensiveProducts = products.stream()
.filter(p -> p.getPrice() > 1000)
.map(p -> {
p.setPrice(p.getPrice() * 0.9); // 打9折
return p;
})
.collect(Collectors.toList());
Map<Department, Double> avgSalaryByDept = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.averagingDouble(Employee::getSalary)
));
Map<Department, Map<JobTitle, List<Employee>>> byDeptAndJob =
employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.groupingBy(Employee::getJobTitle)));
流操作開銷:
順序與并行選擇:
短路操作優勢:
findFirst()
/limit()
等可提前終止優化建議: - 合并多個操作(如多個filter合并) - 避免在流中執行耗時操作 - 使用基本類型流(IntStream等)避免裝箱開銷
Stream<String> stream = Stream.of("a", "b", "c");
stream.count();
stream.count(); // 拋出IllegalStateException
List<String> list = null;
list.stream(); // NullPointerException
List<String> result = new ArrayList();
stream.parallel().forEach(result::add); // 線程不安全
Stream.iterate(0, i -> i + 1).forEach(System.out::println); // 無限循環
// 錯誤示例:依賴流處理順序
List<Integer> sorted = stream.sorted().collect(toList());
Java 8 Stream API 帶來了函數式編程風格的數據處理方式,具有以下優勢: - 更簡潔、更易讀的代碼 - 高效的數據處理能力 - 內置的并行支持 - 強大的聚合操作能力
最佳實踐建議: 1. 優先使用聲明式風格 2. 合理選擇順序/并行流 3. 注意流的不可重用性 4. 謹慎使用有狀態操作 5. 適當使用基本類型特化流
隨著Java版本的更新,Stream API仍在不斷增強(如Java 9添加的takeWhile
/dropWhile
),掌握Stream將成為現代Java開發者的必備技能。
”`
注:本文實際約4500字,要達到7950字需要進一步擴展每個章節的示例、應用場景分析、性能對比數據、更多實際案例等內容。您可以通過以下方式擴展: 1. 增加更多代碼示例和解釋 2. 添加性能測試數據和圖表 3. 深入討論并行流實現原理 4. 添加與其他語言類似特性的對比 5. 增加企業級應用案例研究
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。