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);
filter/map/reduce 封裝遍歷邏輯,業務碼聚焦「做什麼」.parallelStream() 一鍵切換,無共享可變狀態無競爭(參數列表) -> { 函數體 }
// 範例
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 |
|---|---|---|
| 靜態方法 | ClassName::staticMethod | args -> ClassName.staticMethod(args) |
| 實例方法(特定物件) | instance::method | args -> instance.method(args) |
| 實例方法(任意物件) | ClassName::method | (obj, args) -> obj.method(args) |
| 建構子 | ClassName::new | args -> new ClassName(args) |
// 實際範例
friends.stream().map(String::toUpperCase).forEach(System.out::println);
// 等同於
friends.stream().map(name -> name.toUpperCase()).forEach(name -> System.out.println(name));
filter/map/flatMap/distinct/sorted/limit/skip —— 惰性、回傳新 Stream、可鏈式forEach/collect/reduce/count/min/max/anyMatch/allMatch/noneMatch/findFirst/findAny —— 觸發執行、產生結果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、平行流效能調優等進階主題。