1、Lambda 表達式javascript
簡單來講,編程中提到的 lambda 表達式,一般是在須要一個函數,可是又不想費神去命名一個函數的場合下使用,也就是指匿名函數。html
連接:知乎java
先舉一個普通的 Python 例子:將一個 list 裏的每一個元素都平方:express
map( lambda x: x*x, [y for y in range(10)] )
這段代碼表達的意思和下面的意思同樣:編程
def sq(x): return x * x map(sq, [y for y in range(10)])
a = [1, 2, 3]
和閉包
f = lambda x : x + 1
等號右邊的東西徹底能夠脫離等號左邊的東西而存在,等號左邊的名字只是右邊之實體的標識符。若是你能習慣 [1, 2, 3] 單獨存在,那麼 lambda x : x + 1 也能單獨存在其實也就不難理解了,它的意義就是給「某個數加一」這一運算自己。編程語言
如今回頭來看 map() 函數,它能夠將一個函數映射到一個可枚舉類型上面。沿用上面給出的 a 和 f,能夠寫:map(f, a)
map( lambda x : x + 1, [1, 2, 3] )
這樣的寫法時,你會發現本身若是能將「遍歷列表,給遇到的每一個元素都作某種運算」的過程從一個循環裏抽象出來成爲一個函數 map,而後用 lambda 表達式將這種運算做爲參數傳給 map 的話,考慮事情的思惟層級會高出一些來,須要顧及的細節也少了一點。ide
2、Java中應用Lambda 表達式函數式編程
這一部分會介紹 Java8 Lambda 表達式產生的背景和用法,以及 Lambda 表達式與匿名類的不一樣這些內容,函數
首先看一個Java中匿名內部類的示例:
button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("The button was clicked using old fashion code!"); } });
這是使用匿名內部類的方法向一個 UI 組件添加 ActionListener,也能夠寫成:
button.addActionListener( (e) -> { System.out.println("The button was clicked. From Lambda expressions !"); });
後一種方式就是採用了Lambda表達式的方法來進行相同的操做。
若是忽視註解(Annotations)、泛型(Generics)等特性,自 Java 語言誕生時起,它的變化並不大。Java 一直都致力維護其對象至上的特徵,在使用過 JavaScript 之類的函數式語言以後,Java 如何強調其面向對象的本質,以及源碼層的數據類型如何嚴格變得更加清晰可感。其實,函數對 Java 而言並不重要,在 Java 的世界裏,函數沒法獨立存在。在函數式編程語言中,函數是一等公民,它們能夠獨立存在,你能夠將其賦值給一個變量,或將他們當作參數傳給其餘函數。JavaScript 是最典型的函數式編程語言。點擊此處以及此處能夠清楚瞭解 JavaScript 這種函數式語言的好處。函數式語言提供了一種強大的功能——閉包,相比於傳統的編程方法有不少優點,閉包是一個可調用的對象,它記錄了一些信息,這些信息來自於建立它的做用域。Java 如今提供的最接近閉包的概念即是 Lambda 表達式,雖然閉包與 Lambda 表達式之間存在顯著差異,但至少 Lambda 表達式是閉包很好的替代者。
Lambda表達式:
Lambda 表達式是一種匿名函數(對 Java 而言這並不徹底正確,但如今姑且這麼認爲),簡單地說,它是沒有聲明的方法,也即沒有訪問修飾符、返回值聲明和名字。
你能夠將其想作一種速記,在你須要使用某個方法的地方寫上它。當某個方法只使用一次,並且定義很簡短,使用這種速記替代之尤爲有效,這樣,你就沒必要在類中費力寫聲明與方法了。
Java 中的 Lambda 表達式一般使用 (argument) -> (body)
語法書寫,例如:
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
或者能夠寫做:
(int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return 3.1415 };
(int a)
與(a)
效果相同(a, b)
或 (int a, int b)
或 (String a, int b, float c)
() -> 42
a -> return a*a
使用Lambda表達式後,線程能夠經過如下方法初始化:
//舊方法: new Thread(new Runnable() { @Override public void run() { System.out.println("Hello from thread"); } }).start(); //新方法: new Thread( () -> System.out.println("Hello from thread") ).start();