# 怎么從零開始學習Java8 Stream
## 前言
Java 8于2014年發布,引入了革命性的Stream API,徹底改變了Java集合操作的方式。Stream提供了一種高效且聲明式處理數據集合的方法,使代碼更簡潔、更易讀。本文將系統性地介紹如何從零開始學習Java8 Stream,涵蓋基礎概念、核心操作、使用場景和性能優化等內容。
---
## 目錄
1. [Stream概述](#一stream概述)
2. [創建Stream的6種方式](#二創建stream的6種方式)
3. [Stream的中間操作](#三stream的中間操作)
4. [Stream的終端操作](#四stream的終端操作)
5. [并行流與性能優化](#五并行流與性能優化)
6. [實際應用案例](#六實際應用案例)
7. [常見問題與陷阱](#七常見問題與陷阱)
---
## 一、Stream概述
### 1.1 什么是Stream
Stream是Java 8引入的處理集合(Collection)數據的抽象概念,可以看作高級版本的Iterator。主要特點包括:
- **不存儲數據**:只描述對數據的計算操作
- **函數式編程風格**:支持lambda表達式
- **延遲執行**:終端操作觸發實際計算
- **可并行化**:parallelStream()實現并行處理
### 1.2 與傳統集合操作對比
```java
// 傳統方式:篩選+排序+輸出
List<String> filtered = new ArrayList<>();
for(String name : names) {
if(name.startsWith("A")) {
filtered.add(name);
}
}
Collections.sort(filtered);
for(String name : filtered) {
System.out.println(name);
}
// Stream方式
names.stream()
.filter(name -> name.startsWith("A"))
.sorted()
.forEach(System.out::println);
操作類型 | 特點 | 示例 |
---|---|---|
中間操作 | 返回Stream,可鏈式調用 | filter(), map() |
終端操作 | 返回具體結果或產生副作用 | forEach(), collect() |
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<Double> randoms = Stream.generate(Math::random);
// 遞增序列
Stream<Integer> numbers = Stream.iterate(0, n -> n + 2);
IntStream intStream = IntStream.range(1, 100); // 1-99
LongStream longStream = LongStream.of(1L, 2L, 3L);
try(Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
lines.forEach(System.out::println);
}
操作 | 描述 | 示例 |
---|---|---|
filter() | 條件過濾 | .filter(s -> s.length() > 3) |
distinct() | 去重 | .distinct() |
limit() | 截斷流 | .limit(10) |
skip() | 跳過元素 | .skip(5) |
// 提取屬性
List<String> names = users.stream()
.map(User::getName)
.collect(Collectors.toList());
// 扁平化處理
List<String> words = lines.stream()
.flatMap(line -> Arrays.stream(line.split(" ")))
.collect(Collectors.toList());
// 自然排序
Stream.of("Banana", "Apple", "Pear")
.sorted();
// 自定義排序
users.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.peek(System.out::println) // 查看流經的元素
boolean anyMatch = list.stream().anyMatch(s -> s.contains("a"));
Optional<String> first = list.stream().findFirst();
// 求和
int sum = IntStream.of(1,2,3).sum();
// 自定義歸約
Optional<Integer> total = numbers.reduce((a,b) -> a*b);
// 轉換為List
List<String> list = stream.collect(Collectors.toList());
// 分組
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// 拼接字符串
String joined = strings.collect(Collectors.joining(", "));
IntSummaryStatistics stats = numbers.collect(
Collectors.summarizingInt(Integer::intValue));
// 獲取count, sum, min, average, max
List<String> list = ...;
// 方式1
Stream<String> parallelStream = list.parallelStream();
// 方式2
Stream<String> parallelStream = list.stream().parallel();
long start = System.currentTimeMillis();
// 順序流操作
long end = System.currentTimeMillis();
long parallelStart = System.currentTimeMillis();
// 并行流操作
long parallelEnd = System.currentTimeMillis();
// 統計單詞頻率
Map<String, Long> wordCount =
Files.lines(Paths.get("book.txt"))
.flatMap(line -> Arrays.stream(line.split("\\W+")))
.collect(Collectors.groupingBy(String::toLowerCase,
Collectors.counting()));
// 獲取所有訂單中的商品列表
List<Product> products = orders.stream()
.flatMap(order -> order.getItems().stream())
.distinct()
.collect(Collectors.toList());
// 模擬SQL查詢:SELECT name FROM users WHERE age > 20 ORDER BY age DESC
List<String> result = users.stream()
.filter(u -> u.getAge() > 20)
.sorted(comparing(User::getAge).reversed())
.map(User::getName)
.collect(toList());
Stream<String> stream = list.stream();
stream.forEach(...); // OK
stream.count(); // 拋出IllegalStateException
// 使用Optional避免NPE
Optional<String> max = list.stream()
.max(Comparator.naturalOrder());
// 使用peek查看中間結果
.stream()
.peek(e -> System.out.println("After filter: " + e))
.filter(...)
.peek(e -> System.out.println("After map: " + e))
.map(...)
Java8 Stream徹底改變了Java處理集合數據的方式。通過本文的系統學習,您應該已經掌握了: 1. Stream的核心概念與操作流程 2. 各種創建和操作方法的使用場景 3. 并行流的使用技巧和注意事項 4. 實際開發中的典型應用模式
建議通過實際項目練習來鞏固知識,開始時可以嘗試重構現有的循環代碼為Stream操作。隨著熟練度的提高,您將能寫出更簡潔高效的Java代碼。
延伸學習資源: - 《Java 8實戰》 - Oracle官方Stream文檔 - GitHub上的開源項目代碼閱讀 “`
注:本文實際約4500字,要達到6500字需要擴展以下內容: 1. 增加更多實際案例(如JSON處理、文件分析等) 2. 添加性能對比測試數據 3. 深入講解Collector自定義實現 4. 增加與RxJava/React式編程的對比 5. 添加更多調試和異常處理技巧 需要進一步擴展哪部分內容可以告訴我。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。