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

Java 8 函數式介面與 Lambda 表達式:核心關係深度解析

     編輯:Java 程式設計入門

函數式介面:Lambda 表達式的類型基石

函數式介面本質上是一個單一抽象方法(SAM,Single Abstract Method)的介面。Java 8 引入 @FunctionalInterface 註解標識,編譯器會強制檢查是否符合 SAM 契約。其核心價值在於:當方法參數為函數式介面時,調用者可傳入 Lambda 表達式作為實參,實現行為參數化。

SAM 契約的例外情況

  • default 方法:Java 8 新增,提供預設實現,不破壞 SAM 契約。解決介面演進兼容性問題(如 Collection.stream())
  • static 方法:介面靜態方法,同樣不影響 SAM
  • Object 類別的公共方法:equals()、hashCode()、toString() 等不計入抽象方法計數

JDK 內建函數式介面

Java 8 前已存在的介面均已標註 @FunctionalInterface:

  • Runnable、Callable<V>:執行緒任務
  • Comparator<T>:比較邏輯
  • FileFilter、PathMatcher:檔案/路徑匹配
  • InvocationHandler:動態代理
  • 各類 EventListener:ActionListener、PropertyChangeListener 等

自定義函數式介面範例

@FunctionalInterface
public interface Converter<F, T> {
    T convert(F from);
}

// 使用 Lambda 實現
Converter<String, Integer> converter = from -> Integer.valueOf(from);
Integer result = converter.convert("123"); // 123

核心函數式介面詳解(java.util.function)

介面參數返回值核心方法典型用途
Function<T, R>TRapply(T t)資料轉換/映射
Predicate<T>Tbooleantest(T t)條件判斷/過濾
Consumer<T>Tvoidaccept(T t)消費型操作(列印、日誌)
Supplier<T>無Tget()延遲初始化/工廠方法
BinaryOperator<T>T, TTapply(T t1, T t2)歸約/聚合操作
UnaryOperator<T>TTapply(T t)單元素轉換

方法引用與建構子引用(:: 操作符)


// 靜態方法引用
Function<String, Integer> parser = Integer::valueOf;

// 實例方法引用
String str = "Hello";
Supplier<Integer> lengthSupplier = str::length;

// 建構子引用
Supplier<ArrayList<String>> listFactory = ArrayList::new;
Function<Integer, String[]> arrayFactory = String[]::new;

Lambda 表達式語法精要

// 完整語法
(參數列表) -> { 方法體; return 結果; }

// 單參數可省略括號
x -> x * x

// 無參數
() -> System.out.println("Hello")

// 單語句可省略大括號和 return
(x, y) -> x + y

變數捕獲規則

  • 可存取成員變數和靜態變數
  • 區域變數需為 final 或實際上 final(effectively final):Lambda 體內不得修改其值
  • 這確保了 Lambda 表達式在併發環境下的執行緒安全性

實戰應用模式

Stream API 配合 Lambda

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 過濾 + 轉換 + 收集
List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 歸約求和
int totalLength = names.stream()
    .mapToInt(String::length)
    .sum();

自定義方法接收 Lambda

public void process(String input, Function<String, String> processor) {
    String result = processor.apply(input);
    System.out.println("處理結果: " + result);
}

// 調用
process("hello", s -> s.toUpperCase());
process("world", s -> new StringBuilder(s).reverse().toString());

總結:函數式介面與 Lambda 的共生關係

  1. 函數式介面提供目標類型:Lambda 表達式本身無類型,需透過目標類型推導
  2. Lambda 提供實現邏輯:替代匿名內部類,語法簡潔,語義清晰
  3. 方法引用進一步簡化:當 Lambda 僅調用現有方法時,使用 :: 更加直觀
  4. Stream API 釋放威力:函數式介面 + Lambda + Stream 構成 Java 8 函數式程式設計的核心三角
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved