Lambda 表達式是 Java 8 引入的重要特性,為 Java 帶來函數式程式設計支援。雖然初接觸時閱讀較費力,但習慣後能顯著簡化程式碼,且 Python、Swift 等語言皆有類似概念,學習價值極高。
([參數...]) -> { 陳述式; }
方括號表參數可選,即無參數時括號可留空。
Java 8 在 Iterable 新增 forEach(Consumer action),接受 Lambda 表達式。傳統三行迴圈可縮減為一行:
list.forEach(item -> System.out.println(item));
更可用方法參考 :: 進一步簡化:list.forEach(System.out::println)。:: 前為作用域(類別或物件),後為具體方法。注意 Arrays.asList() 回傳的是 java.util.Arrays.ArrayList 內部類,非 java.util.ArrayList。
Lambda 極大簡化匿名內部類寫法:
// 傳統寫法
new Thread(new Runnable() {
public void run() { System.out.println("Running"); }
}).start();
// Lambda 寫法
new Thread(() -> System.out.println("Running")).start();
Arrays.sort() 配合 Lambda 可單行完成自訂排序:
Arrays.sort(array, (a, b) -> b - a); // 遞減排序
範例展示多參數 Lambda 寫法。文中提及 Arrays.stream() 回傳 Stream 物件,支援 map、reduce、filter 等操作,後續將專文介紹。
Predicate<T> 代表回傳 boolean 的函數式介面。範例展示串接 and()、or() 進行複合篩選:
List result = list.stream()
.filter(s -> s.length() > 4)
.filter(s -> s.endsWith("A"))
.collect(Collectors.toList());
Lambda 相當於匿名內部類,引用外部區域變數時,該變數必須是 final 或實際上不再修改(effectively final),否則編譯報錯。這與匿名內部類規則一致。