Java 8 中的 lambda 表示式
Lambda 表示式是 Java 8 最受歡迎的功能。人們將函數語言程式設計的概念引入了 Java 這門完全物件導向的指令式程式設計語言。關於函數語言程式設計是如何運作的,這個話題超出了本文的範圍,不過我們會提煉出它一個明顯有別於我們所經常使用的 OOP (物件導向程式設計)的功能來加以討論。
在本文中, 我們將瞭解到 lambda 表示式具體是什麼東西,還有就是它們是如何將自己融入整個 Java 生態系統的。我們也會對沒有使用 lambda 表示式的程式碼以及後面使用 lambda 進行重構的示例程式碼進行一下觀察和比較。
瞭解 Lambda 表示式
Lambda 表示式是一塊我們可以將其傳入並執行的程式碼。對於作為 Java 程式設計師的我們而言,並不會怎麼習慣將一塊程式碼傳入一個函式這樣的方式。我們的習慣是將定義的程式碼封裝到方法體裡面,然後通過物件引用來加以執行,如下所示:
public class LambdaDemo { public void printSomething(String something) { System.out.println(something); } public static void main(String[] args) { LambdaDemo demo = new LambdaDemo(); String something = "I am learning Lambda"; demo.printSomething(something); } }
這是經典 OOP 開發正規化的風格,將方法實現對呼叫者隱藏。呼叫者只是簡單地向方法傳入一個變數,然後方法拿這個變數會執行一些操作,並返回另外一個變數值,或者如我們的示例所示,會產生一些副作用效果。
現在我們要來看看一種使用了行為傳遞方式,而不是變數傳遞的等效實現。為此,我們要建立一個函式式的介面,裡面定義的是對行為,而不是對方法的抽象。一個函式式介面是一種只有一個方法的介面:
public class LambdaDemo { interface Printer { void print(String val); } public void printSomething(String something, Printer printer) { printer.print(something); } }
在上面的程式碼實現中, Printer 介面負責所有的列印操作。printSomething 方法不再對行為進行定義,而是執行由 Printer 定義的行為:
public static void main(String[] args) { LambdaDemo demo = new LambdaDemo(); String something = "I am using a Functional interface"; Printer printer = new Printer() { @Override public void print(String val) { System.out.println(val); } }; demo.printSomething(something, printer); }
讀者中比較有觀察能力的可能已經注意到,我並沒有在這裡做什麼新的事情。的確是這樣的,因為我還沒有應用到 lambda 表示式。我們只是簡單地建立了一個 Printer 介面的具體實現,並將它傳入了 printSomething 方法。
上面的示例旨在給我們帶來一個將 Lambda 表示式引入到 Java 中的關鍵目標:
Lambda 表示式原被用於定義一個函式式介面的內聯實現。
在我們使用 lambda 表示式對上面的示例進行重構之前,先來學習一下必要的語法知識:
(param1,param2,param3...,paramN) - > {//程式碼塊;}
一個 lambda 表示式的組成,是一個我們通常會定義在方法宣告中的,以括弧封閉起來並以逗號分隔的引數列表,後面跟上一個箭頭標記指向要執行的程式碼。現在,讓我們來使用 lambda 對上面的程式碼進行重構:
public static void main(String[] args) { LambdaDemo demo = new LambdaDemo(); String something = "I am learning Lambda"; /**/ Printer printer = (String toPrint)->{System.out.println(toPrint);}; /**/ demo.printSomething(something, printer); }
看上去非常緊湊且美觀。因為函式式介面只宣告瞭一個方法,所以在 lambda 的第一部分中傳入的引數被自動地對映到了方法的引數列表上,而箭頭右邊的程式碼則被當做是方法的具體實現了。
為什麼要使用 Lambda 表示式
如同前面的示例, lambda 表示式能讓我們擁有更加緊湊的程式碼,更加易於閱讀和跟蹤。這個在效能和多核處理方法還有其它的一些好處,不過它們得在你瞭解了 Streams API 以後才有用,而這個超出了本文的範圍。
通過比較使用和沒使用 lambda 的 main 方式實現,當它一下子把程式碼變得簡短的時候,我們切實地看到了 lambda 表示式的能力:
public static void main(String[] args) { LambdaDemo demo = new LambdaDemo(); String something = "I am learning Lambda"; /**/ Printer printer = (String toPrint)->{System.out.println(toPrint);}; /**/ demo.printSomething(something, printer); }
我們還可以讓程式碼比這裡所展示的更簡潔。這樣的事情發生時,你甚至無需指定箭頭左邊引數的型別,而其型別會由編譯器根據介面方法的形參推斷出來。
Printer printer = (toPrint)->{System.out.println(toPrint);};
我們還可以做得更好。lambda 的另外一個特性就是: 如果只有一個引數, 就可以將括弧完全消除掉。同樣的,如果在箭頭右邊只有一條語句,也可以將大括號去掉:
Printer printer = toPrint -> System.out.println(toPrint);
現在的程式碼看起來真正變得可愛起來,不過我們才剛剛開始而已。如果我們的介面方法並不要任何引數,那就可以將生命用一對空的括弧替換掉:
() -> System.out.println("anything");
如果我們只是內聯一個 lambda 進去,而不去首先建立一個物件然後將其傳入到 saySomething 方法,會如何呢:
public static void main(String[] args) { LambdaDemo demo = new LambdaDemo(); String something="I am Lambda"; /**/ demo.printSomething(something, toPrint -> System.out.println(toPrint)); }
現在我們才是真的在談論函數語言程式設計了。我們的 main 函式體從一開始的 9 行程式碼減少到了 3 行。這樣緊湊的程式碼使得 lambda 表示式對於 Java 程式設計師非常有吸引力。
總結
在本文中,我們對 Java 中的 Lambda 表示式進行了簡單介紹,瞭解了它們可以被用來提升函式式介面實現的程式碼質量。關注這個網站可以獲得有關 Lambda 的更多知識,因為我還會在這裡涉及 Stream API 的內容,並對其如何同 Collections 框架結合在一起使用來給予我們更多 Lambda 的好處進行討論。
原文地址:https://dzone.com/articles/lambda-expressions-in-java-8
相關文章
- [轉]Java 8 的 lambda 表示式 Java 8 的 lambda 表示式Java
- Java8中的Lambda表示式Java
- Java 8 Lambda 表示式Java
- java 8 lambda表示式Java
- Java8的Lambda表示式Java
- Java 8中的Lambda表示式最佳實踐Java
- Java8-Lambda表示式Java
- java8 lambda表示式Java
- 掌握 Java 8 Lambda 表示式Java
- Java 中的 Lambda 表示式Java
- 深入探索 Java 8 Lambda 表示式Java
- java8特性-lambda表示式Java
- Java中Lambda表示式的使用Java
- 《Java 8 in Action》Chapter 3:Lambda表示式JavaAPT
- Java 8新特性(一):Lambda表示式Java
- Java 8 lambda 表示式10個示例Java
- 【譯】java8之lambda表示式Java
- Java 8 流特性和 Lambda 表示式Java
- Java8特性詳解 lambda表示式(二):流式處理中的lambdaJava
- Java 8的Lambda表示式的陰暗面Java
- Java中Lambda表示式的應用Java
- Java的Lambda表示式Java
- Java中lambda表示式詳解Java
- Java8新特性(1):Lambda表示式Java
- java8學習:lambda表示式(2)Java
- java8學習:lambda表示式(1)Java
- Java8新特性(一)-Lambda表示式Java
- java8 新特性之Lambda 表示式Java
- Java8 新特性之 Lambda 表示式Java
- Lambda表示式之爭:Scala vs Java 8Java
- Java 8 vs. Scala(一): Lambda表示式Java
- Java | Lambda表示式Java
- Lambda表示式(Java)Java
- java lambda 表示式Java
- Java Lambda表示式Java
- Java中Lambda表示式的進化之路Java
- Java 8 Lambda表示式一看就會Java
- Java8 Lambda表示式、Optional類淺析Java