首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 函數式編程(七):MapReduce 模式與 reduce 歸約操作詳解

     編輯:Java 相關知識

前言

Map(映射)與 Reduce(歸約)是函數式編程兩大基石。Java 8 通過 map/mapToInt 等中間操作實現 Map,通過 reduce 終端操作實現 Reduce。本文從基礎求和到極值查找、字符串拼接,全方位演示歸約威力。

Map 階段:屬性提取與類型轉換

// 提取名字長度 → IntStream
IntStream lengths = friends.stream().mapToInt(String::length);

// 基本類型流專用聚合
int total = lengths.sum();        // 總和
int maxLen = lengths.max().orElse(0);
double avg = lengths.average().orElse(0);

Reduce 核心簽名

// 1. 無初始值,返回 Optional
Optional<T> reduce(BinaryOperator<T> accumulator)

// 2. 有初始值,返回 T
T reduce(T identity, BinaryOperator<T> accumulator)

// 3. 並行專用:identity + accumulator + combiner
 U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner)

實戰一:尋找最長名字(無初始值)

Optional<String> longest = friends.stream()
    .reduce((name1, name2) -> 
        name1.length() >= name2.length() ? name1 : name2);

longest.ifPresent(name -> System.out.println("Longest: " + name));
// Longest: Brian

執行流程:Brian vs Nate → Brian → Brian vs Neal → Brian → ... 累加器不斷攜帶「當前最長」向後比較。

實戰二:指定默認值(有初始值)

String defaultName = "Steve";
String result = friends.stream()
    .reduce(defaultName, (n1, n2) -> n1.length() >= n2.length() ? n1 : n2);
// 若 friends 為空,直接返回 "Steve"

實戰三:字符串拼接(reduce 變體)

// 手寫 reduce 拼接
String joined = friends.stream()
    .reduce("", (a, b) -> a + (a.isEmpty() ? "" : ", ") + b);
// Brian, Nate, Neal, Raju, Sara, Scott

// 生產級:Collectors.joining
String joined = friends.stream().collect(Collectors.joining(", "));

Collect vs Reduce:收集器模式

collect(Collector) 是 reduce 的泛化,分離「累加容器創建、元素累加、容器合併、最終轉換」四步,支援並行。常用收集器:

// 轉 List/Set
.toList() / .toSet()

// 分組
.groupingBy(Person::getDept)

// 多級分組 + 下游聚合
.groupingBy(Person::getDept, 
    groupingBy(Person::getGender, averagingDouble(Person::getSalary)))

// 字符串拼接
.joining(", ", "[", "]") // [Brian, Nate, ...]

性能對比:reduce vs 迴圈

場景推薦理由
簡單聚合(sum/max)基本類型流 .sum()/.max()內部優化,避免裝箱
複雜對象歸約reduce(identity, acc, combiner)並行友好,combiner 必須滿足結合律
收集到集合/Mapcollect(Collectors.xxx)專用收集器高效合併
字符串拼接Collectors.joining內部用 StringJoiner,避免 O(n²)

總結

map 負責「形狀轉換」,reduce 負責「值累積」。掌握三種 reduce 重載與 Collector 四步法,能優雅解決從求和到複雜分組聚合的所有歸約問題。下一篇將探討 StringJoiner 與 Collectors.joining 的字符串拼接最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved