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

Java 函數式程式設計入門(一):Lambda 表達式與 Stream API 核心思想

     編輯:Java 相關知識

從命令式到聲明式:思維範式轉移

Java 8 引入 Lambda 與 Stream,標誌著從「告訴電腦怎麼做」轉向「描述想要什麼」。以查找城市為例:

命令式風格(舊)

boolean found = false;
for (String city : cities) {
    if (city.equals("Chicago")) { found = true; break; }
}
System.out.println("Found Chicago? " + found);

庫方法簡化(中)

System.out.println("Found Chicago? " + cities.contains("Chicago"));

函數式風格(新)

// 更複雜的例子:價格 > 20 打 9 折後求和
BigDecimal total = prices.stream()
    .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)
    .map(price -> price.multiply(BigDecimal.valueOf(0.9)))
    .reduce(BigDecimal.ZERO, BigDecimal::add);

函數式風格七大優勢

  1. 無可變變數:消除迴圈計數器、累加器等中間狀態,Bug 溫床大減
  2. 迭代內建化:filter/map/reduce 封裝遍歷邏輯,業務碼聚焦「做什麼」
  3. 程式碼簡潔:同樣功能行數減少 50%+
  4. 可讀性強:程式碼像需求文檔一樣閱讀(過濾 → 轉換 → 歸約)
  5. 易並行化:.parallelStream() 一鍵切換,無共享可變狀態無競爭
  6. 惰性求值:中間操作不執行,終端操作才觸發,支援無限流
  7. 組合性:操作可任意組合管道,復用極高

Lambda 表達式核心語法

(參數列表) -> { 函數體 }
// 範例
price -> price.compareTo(BigDecimal.valueOf(20)) > 0           // 單參數、單表達式(隱式返回)
(price) -> { return price.compareTo(BigDecimal.valueOf(20)) > 0; } // 區塊體、顯式 return
(String a, String b) -> a.length() - b.length()                // 多參數
() -> System.out.println("Hello")                              // 無參數

函數式介面

單一抽象方法的介面,可隱式轉換為 Lambda:

  • Predicate<T>:boolean test(T t)(過濾)
  • Function<T,R>:R apply(T t)(轉換)
  • Consumer<T>:void accept(T t)(消費)
  • Supplier<T>:T get()(供給)
  • BinaryOperator<T>:T apply(T t1, T t2)(歸約)

可用 @FunctionalInterface 註解標記,編譯器會強制檢查。

方法引用:Lambda 的語法糖

當 Lambda 僅轉發呼叫現有方法時,用方法引用更簡潔:

類型語法對應 Lambda
靜態方法ClassName::staticMethodargs -> ClassName.staticMethod(args)
實例方法(特定物件)instance::methodargs -> instance.method(args)
實例方法(任意物件)ClassName::method(obj, args) -> obj.method(args)
建構子ClassName::newargs -> new ClassName(args)
// 實際範例
friends.stream().map(String::toUpperCase).forEach(System.out::println);
// 等同於
friends.stream().map(name -> name.toUpperCase()).forEach(name -> System.out.println(name));

Stream 三大操作類別

  1. 中間操作:filter/map/flatMap/distinct/sorted/limit/skip —— 惰性、回傳新 Stream、可鏈式
  2. 終端操作:forEach/collect/reduce/count/min/max/anyMatch/allMatch/noneMatch/findFirst/findAny —— 觸發執行、產生結果
  3. 短路操作:limit/skip/anyMatch/allMatch/noneMatch/findFirst/findAny —— 可提前終止,支援無限流

實戰模式:策略封裝與關注點分離

// 交易模板:將策略(事務管理、審計)內建化
public void runInTransaction(TransactionCallback callback) {
    Transaction tx = getTransaction();
    try {
        callback.execute(tx);
        tx.commit();
        auditLog.success();
    } catch (Exception e) {
        tx.rollback();
        auditLog.failure(e);
        throw e;
    }
}

// 使用
runInTransaction(tx -> {
    // 業務邏輯專注核心領域
    orderService.createOrder(userId, items);
});

總結

Lambda + Stream 不是語法糖,而是程式設計範式的升級。掌握關鍵在於:

  • 拥抱不可變性,拒絕可變狀態
  • 用組合替代繼承,用函數替代物件傳遞
  • 信任庫函數處理迭代、並行、優化細節

下一章將深入 Collector、Optional、平行流效能調優等進階主題。

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