Java 中的函數式編程(Functional Programming):Lambda 初識

Java 8 發佈帶來的一個主要特性就是對函數式編程的支持。html

而 Lambda 表達式就是一個新的而且很重要的一個概念。java

它提供了一個簡單而且很簡潔的編碼方式。web

首先從幾個簡單的 Lambda 表達式的例子開始瞭解 Java 中的函數式編程。express

 

Lambda 表達式初識:編程

首先定義一個 Lambda 表達式:oracle

x -> x + 1

這個表達式輸入參數是一個 x,而後對這個參數 x 的操做是加 1,而後將這個結果返回,即返回值。app

 

從這個簡單的 Lambda 表達式能夠看出 Lambda 表達式的語法格式是:ide

(類型 參數1, 類型 參數2) -> { 方法體 }

參數的小括號能夠省略不寫;函數式編程

方法體的花括號也能夠省略不寫(這是由於方法體有兩種類型:單行代碼 或者是 代碼塊,單行代碼不須要花括號同時 return 關鍵字省略),例如:函數

(int x, int y) -> { return x + y; }
(int x, int y) -> x + y
x -> x + 1
() -> 3.14
(String s) -> { System.out.println(s); }

第一個表達式接收兩個參數 x 和 y,返回 x + y;

第二個表達式和第一個表達式同樣,省略了花括號和 return 關鍵字;

第三個表達式接收一個參數,返回 x+1;

第四個表達式不接收任何參數,返回數字 3.14;

第五個表達式接收一個參數,沒有返回值。

 

看到第三個表達式,不少新接觸 Lambda 表達式的朋友難免會有兩個疑問:x 的類型是什麼?這個整個函數的類型是什麼呢,怎麼表示它?

接下來就要引入另外一個關鍵的內容,即 java.util.function 包,官方對它的定義是:「Functional interfaces provide target types for lambda expressions and method references. 」 即爲定義函數對象提供的類,也就是如何存儲一個函數對象。也就是它專門用來解決上面提出的這個問題:

回到剛剛的這個 Lambda 表達式:x -> x + 1,這個表達式接收一個參數,返回一個參數,咱們能夠將這個 Lambda 表達式表示爲:

Function<Integer, Integer> add = x -> x + 1;
Function<String, String> concat  = x -> x + 1;

第一行代碼裏的 x 的類型是 Integer,它表示將 Integer 類型的參數 x 加 1 而後並返回,即若是參數是 2,那麼這行代碼返回 3。

第二行代碼裏的 x 的類型是 String,它表示將 String 類型的參數 x 和 "1" 鏈接並返回,即若是參數是 "hi", 那麼這行代碼返回 hi1。

 

 

兩個參數:

若是咱們須要定義兩個參數的函數要怎麼寫呢?好比將兩個 Integer 類型的 x,y 進行求和並返回結果?

這裏咱們須要另外一個類 BiFunction<T, U, R>,T表示第一個輸入參數的類型,U表示第二個輸入參數的類型,R表示返回值的類型,因此咱們的答案是:

BiFunction<Integer, Integer, Integer> sum = (x, y) -> x + y;

 

只輸入參數不返回結果:

若是咱們須要定義一個只輸入參數卻不返回結果的函數要怎麼寫?這裏咱們須要另外一個類 Consumer<T>

Consumer<String> sayHi = name -> System.out.println("hi, " + name);

若是想要定義輸入兩個參數卻不返回結果的函數須要用 BiConsumer<T, U> 類,用法和前面提到的 BiFunction 類型同樣,再也不贅述。

 

 

只返回結果不輸入參數:

若是咱們須要定義一個只返回結果但不須要輸入參數的函數要怎麼寫?這裏咱們須要另外一個類 Supplier<T>

Supplier<String> getName = () -> "Carl";

 

如何執行函數:

既然有了函數,那麼這些函數要怎麼執行呢?

答案是用 apply() 方法:

nteger result = add.apply(2);  // 返回 3
String answer = concat.apply("hi");  // 返回 "hi1"
Integer  total = sum.apply(1, 2);  // 返回 3
String name = getName.apply();  // 返回 "Carl"

 

結束語:

以前一直用 C#、Objective-C、Swift 和 Python,由於今年研究生階段的課程以 Java 語言爲主,因此開始瞭解一下 Java。

感興趣的朋友歡迎關注本博客,也歡迎你們留言討論。

 

 

參考資料:

Beginning Java objects by Jacquie Barker

Java SE 8: Lambda Quick Start

The big change in Java SE 8

Functional Programming with Java 8 Functions

 

分享一張半個月前美國小鎮的雪景:

相關文章
相關標籤/搜索