1、lambda含義
lambda表示數學符號「λ」,計算機領域中λ表明「λ演算」,表達了計算機中最基本的概念:「調用」和「置換」。在不少動態語言和C#中都有相應的lambda語法,這類語法都爲了簡化代碼,提升運行效率。
2、lambda 項目的背景,參考這裏。
不管是面嚮對象語言仍是函數式語言,基本數值均可以被動態的封裝入程序動做:面嚮對象語言經過「方法」,函數式語言經過「函數。
介於「方法」和「函數」的定義有不少種,補充下IBM知識庫的解釋:
在面嚮對象語言中,方法不是一階值(First-class value),在函數式語言中,函數是一階值。在函數式語言中,函數能夠做爲另外一個函數的返回值或參數,還能夠做爲一個變量的值,函數能夠嵌套定義,而在面嚮對象語言中的的「方法」作不到這點。
Java能夠說是面嚮對象語言的表明,若是要調用其方法,須要先建立對象。不過Java對象都是「重量級」的,實例化具體的類的對象,須要通過定義和申明 兩個階段。好比定義方法,並給內部字段賦初始值。可是一個對象只包含一個方法的狀況不少,好比實現API中的「回調接口」功能的類,在swing中有接 口:
Java代碼
public interface ActionListener {
void actionPerformed(ActionEvent e);
}
現有的實現方式大可能是:
Java代碼
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.dazzle(e.getModifiers());
}
});
不少現有的類庫都基於這種設計實現,因此對於代碼被明肯定義運行在單獨線程的API來講,匿名內部類尤其重要。這些匿名內部類只存在於建立它的線程中。但 是在並行計算領域,CPU的製造商着力發展多核技術來提高CPU的功能,這麼作幾乎沒法依靠多核的優點來提高其性能。
鑑於回調函數和其餘功能式語法的關係愈來愈密切,因此必須創建儘量的輕量級的數據模型(從編碼角度而言,性能方面下文再說)。對於這點來講匿名內部類的缺點以下:
1. 語法相對複雜。
2. 在調用內部類的上下文中,指引和this的指代容易混淆。
3. 類加載和實例建立語法不可避免。
4. 不能引用外部的非final對象。
5. 不能抽象化控制流程
針對這些問題,lambda項目致力於
1. 消除問題1和問題2,經過引入更簡單的表達式和局部變量的定義規則。
2. 迴避問題3,定義更靈活更友善的語法。這裏只是迴避,類加載和實例化自己不可避免。下文會解釋。
3. 改善問題4,容許用戶使用最終有效的局部變量。
不過lambda項目目前並不能解決全部關於內部類的問題。問題4和問題5沒有徹底解決,這計劃在將類版本中繼續改善。對於性能方面,原文也沒有提,不事後面有些補充。
3、lambda用法
經過上文能夠了解到,lambda語法是針對「回調接口」和「匿名內部類」做出的改進,因此lambda的語法目前僅對於部分接口,這些接口的特色是隻含 一個抽象方法,在lambda項目中,早期稱爲SAM類型(SAM = single abstract method 即單一抽象方法)。在最新的文檔中(即這個版本),它們有了新名字,叫函數接口(functional interface),好比:
1 java.lang.Runnable
2 java.util.concurrent.Callable
3 java.security.PrivilegedAction
4 java.util.Comparator
5 java.io.FileFilter
6 java.nio.file.PathMatcher
7 java.lang.reflect.InvocationHandler
8 java.beans.PropertyChangeListener
9 java.awt.event.ActionListener
10 javax.swing.event.ChangeListener
lambda的語法包括三部分
一、參數列表
二、箭頭符號"->"
三、代碼塊。
其中代碼塊很像一個方法體,return語句將控制權交還給匿名方法(anonymous method,即lambda表達式)的調用者;break和continue不能出如今函數體的頂部,不過能夠出如今內部的循環裏;若是代碼塊得出最終 結果,那麼每個控制路徑(control path) 必須都有返回或拋出異常。
若是代碼塊只有簡單一行,能夠省略return關鍵字和「{}」符號(如下所寫的例子都是基於JDK 1.8 lambda預覽版),好比:
Java代碼
public class LambdaTest {
public static void main(String... args) {
//這裏有{}和return 以及 ;
Runnable r = () -> { System.out.println("hello world"); };
//這裏不須要{}和return
java.util.Comparator<String> c = (String s1, String s2) -> s2.length()-s1.length();
r.run();
System.out.println(c.compare("s1", "12323"));
}
}
輸出爲:
hello world
3
除了這些現有接口,咱們還能夠自定義函數接口:
Java代碼
public class LambdaTest {
interface lambdaInterface {
public void me(String str);
}
public static void main(String... args) {
lambdaInterface li = (String s)->{System.out.println(s);};
li.me("hello world!");
}
}
輸出爲:
hello world!
新的lambda方法從語法上的確是簡化了不少。和lambda第一次發佈的語法相比也優雅不少。java