溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么從零開始學習Java8 Stream

發布時間:2021-10-21 16:14:35 來源:億速云 閱讀:109 作者:iii 欄目:編程語言
# 怎么從零開始學習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);

1.3 Stream操作分類

操作類型 特點 示例
中間操作 返回Stream,可鏈式調用 filter(), map()
終端操作 返回具體結果或產生副作用 forEach(), collect()

二、創建Stream的6種方式

2.1 從集合創建

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

2.2 從數組創建

String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

2.3 使用Stream.of()

Stream<String> stream = Stream.of("a", "b", "c");

2.4 生成無限流

// 隨機數流
Stream<Double> randoms = Stream.generate(Math::random);

// 遞增序列
Stream<Integer> numbers = Stream.iterate(0, n -> n + 2);

2.5 基本類型流

IntStream intStream = IntStream.range(1, 100); // 1-99
LongStream longStream = LongStream.of(1L, 2L, 3L);

2.6 文件流

try(Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
    lines.forEach(System.out::println);
}

三、Stream的中間操作

3.1 篩選與切片

操作 描述 示例
filter() 條件過濾 .filter(s -> s.length() > 3)
distinct() 去重 .distinct()
limit() 截斷流 .limit(10)
skip() 跳過元素 .skip(5)

3.2 映射操作

// 提取屬性
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());

3.3 排序

// 自然排序
Stream.of("Banana", "Apple", "Pear")
      .sorted();

// 自定義排序
users.stream()
     .sorted(Comparator.comparing(User::getAge).reversed())

3.4 調試技巧

.peek(System.out::println) // 查看流經的元素

四、Stream的終端操作

4.1 匹配與查找

boolean anyMatch = list.stream().anyMatch(s -> s.contains("a"));
Optional<String> first = list.stream().findFirst();

4.2 歸約操作

// 求和
int sum = IntStream.of(1,2,3).sum();

// 自定義歸約
Optional<Integer> total = numbers.reduce((a,b) -> a*b);

4.3 收集結果

// 轉換為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(", "));

4.4 統計匯總

IntSummaryStatistics stats = numbers.collect(
    Collectors.summarizingInt(Integer::intValue));
// 獲取count, sum, min, average, max

五、并行流與性能優化

5.1 創建并行流

List<String> list = ...;
// 方式1
Stream<String> parallelStream = list.parallelStream();
// 方式2
Stream<String> parallelStream = list.stream().parallel();

5.2 注意事項

  • 線程安全:確保共享變量線程安全
  • 避免有狀態操作:如sorted()可能降低性能
  • 合適的數據量:小數據量可能適得其反

5.3 性能測試對比

long start = System.currentTimeMillis();
// 順序流操作
long end = System.currentTimeMillis();

long parallelStart = System.currentTimeMillis();
// 并行流操作
long parallelEnd = System.currentTimeMillis();

六、實際應用案例

6.1 數據統計

// 統計單詞頻率
Map<String, Long> wordCount = 
    Files.lines(Paths.get("book.txt"))
         .flatMap(line -> Arrays.stream(line.split("\\W+")))
         .collect(Collectors.groupingBy(String::toLowerCase, 
                  Collectors.counting()));

6.2 多層數據處理

// 獲取所有訂單中的商品列表
List<Product> products = orders.stream()
    .flatMap(order -> order.getItems().stream())
    .distinct()
    .collect(Collectors.toList());

6.3 數據庫式操作

// 模擬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());

七、常見問題與陷阱

7.1 流只能消費一次

Stream<String> stream = list.stream();
stream.forEach(...); // OK
stream.count(); // 拋出IllegalStateException

7.2 空指針問題

// 使用Optional避免NPE
Optional<String> max = list.stream()
    .max(Comparator.naturalOrder());

7.3 性能陷阱

  • 頻繁裝箱拆箱:優先使用IntStream/LongStream
  • 復雜鏈式操作:適當拆分提高可讀性

7.4 調試技巧

// 使用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. 添加更多調試和異常處理技巧 需要進一步擴展哪部分內容可以告訴我。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女