函數式介面本質上是一個單一抽象方法(SAM,Single Abstract Method)的介面。Java 8 引入 @FunctionalInterface 註解標識,編譯器會強制檢查是否符合 SAM 契約。其核心價值在於:當方法參數為函數式介面時,調用者可傳入 Lambda 表達式作為實參,實現行為參數化。
Collection.stream())equals()、hashCode()、toString() 等不計入抽象方法計數Java 8 前已存在的介面均已標註 @FunctionalInterface:
Runnable、Callable<V>:執行緒任務Comparator<T>:比較邏輯FileFilter、PathMatcher:檔案/路徑匹配InvocationHandler:動態代理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
| 介面 | 參數 | 返回值 | 核心方法 | 典型用途 |
|---|---|---|---|---|
Function<T, R> | T | R | apply(T t) | 資料轉換/映射 |
Predicate<T> | T | boolean | test(T t) | 條件判斷/過濾 |
Consumer<T> | T | void | accept(T t) | 消費型操作(列印、日誌) |
Supplier<T> | 無 | T | get() | 延遲初始化/工廠方法 |
BinaryOperator<T> | T, T | T | apply(T t1, T t2) | 歸約/聚合操作 |
UnaryOperator<T> | T | T | apply(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;
// 完整語法
(參數列表) -> { 方法體; return 結果; }
// 單參數可省略括號
x -> x * x
// 無參數
() -> System.out.println("Hello")
// 單語句可省略大括號和 return
(x, y) -> x + y
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();
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());
:: 更加直觀