Java 8 引入函數式編程範式,標誌著 Java 從純面向對象向多範式語言演進。本文通過對比命令式編程,系統梳理函數式編程六大核心特性,並配合代碼示例說明其在實際開發中的優勢。
函數可作為參數傳遞、作為返回值、賦值給變量。以 JavaScript 為例:
// 作為參數傳遞
$("button").click(function(){ $("li").each(function(){ alert($(this).text()) }); });
// 作為返回值(閉包)
function f1(){ var n=1; function f2(){ alert(n); } return f2; }
var result = f1(); result(); // 1
Java 8 通過 FunctionalInterface + Lambda 表達式實現同樣能力,如 Runnable、Comparator、Function<T,R> 等。
純函數不修改外部狀態,僅依賴參數產生返回值。優勢在於:
註:完全無副作用不現實(I/O、DB 操作必須有副作用),函數式語言通過 受控副作用(如 Monad)平衡純度與實用性。
關注「做什麼」而非「怎麼做」。對比命令式循環:
// 命令式
for(int i=0; i
Stream API 將迭代、過濾、映射等控制流封裝在庫中,業務代碼只需描述數據流轉換邏輯。
遞歸調用位於函數末尾時,編譯器可將當前棧幀替換為新調用棧幀,避免棧溢出。Java 目前不直接支援尾遞歸優化(JVM 層面未實現),但可通過 Stream.iterate、尾遞歸手動轉迭代 或 Trampoline 模式繞過限制。
對象創建後狀態不可變,任何修改操作返回新對象。典型例子:String、LocalDateTime、Guava ImmutableList。
int[] arr = {1,3,4,5};
Arrays.stream(arr).map(x -> x+1).forEach(System.out::println); // 2,4,5,6
Arrays.stream(arr).forEach(System.out::println); // 原陣列仍為 1,3,4,5
不可變性帶來:線程安全、緩存友好、領域建模清晰。
得益於無副作用與不可變性,parallelStream() 可無縫切換並行執行,無需鎖同步。代碼量顯著減少:
// 傳統寫法
for(int i=0; i x%2==0? x : x+1).forEach(System.out::println);
Clojure 社區甚至宣稱可將 Java 代碼行數減少 90%。
Java 8 函數式編程不替代 OOP,而是提供正交的抽象工具。善用 Stream API、Lambda、Optional、預設方法,能寫出更簡潔、更安全、更易並行的代碼。建議進階閱讀《Java 8 函數式編程入門》等專書。