jdk1.8新特性-Lambda表達式使用要點

前言

在jdk1.8出來的時候看到過,沒怎麼了解。可是最近再看kafka和spark框架,框架示例中ava版的不少地方用到Lambda表達式,發現使用Lambda表達式代碼確實簡單了好多,有些例子大體能明白什麼意思,可是本身要怎麼使用Lambda有點迷糊,就在網上找了文章普及了下Lambda使用方式,此處記錄下使用要點,不錯例子說明,須要瞭解更多例子進入 Java8 lambda表達式10個示例html

Lambda表達式使用要點

1)lambda表達式僅能放入以下代碼:預約義使用了 @Functional 註釋的函數式接口,自帶一個抽象函數的方法,或者SAM(Single Abstract Method 單個抽象方法)類型。這些稱爲lambda表達式的目標類型,能夠用做返回類型,或lambda目標代碼的參數。例如,若一個方法接收Runnable、Comparable或者 Callable 接口,都有單個抽象方法,能夠傳入lambda表達式。相似的,若是一個方法接受聲明於 java.util.function 包內的接口,例如 Predicate、Function、Consumer 或 Supplier,那麼能夠向其傳lambda表達式。java

2)lambda表達式內能夠使用方法引用,僅當該方法不修改lambda表達式提供的參數。本例中的lambda表達式能夠換爲方法引用,由於這僅是一個參數相同的簡單方法調用。express

list.forEach(n -> System.out.println(n)); 
list.forEach(System.out::println);  // 使用方法引用

然而,若對參數有任何修改,則不能使用方法引用,而需鍵入完整地lambda表達式,以下所示:閉包

list.forEach((String s) -> System.out.println("*" + s + "*"));

事實上,能夠省略這裏的lambda參數的類型聲明,編譯器能夠從列表的類屬性推測出來。框架

3)lambda內部能夠使用靜態、非靜態和局部變量,這稱爲lambda內的變量捕獲。函數

4)Lambda表達式在Java中又稱爲閉包或匿名函數,因此若是有同事把它叫閉包的時候,不用驚訝。工具

5)Lambda方法在編譯器內部被翻譯成私有方法,並派發 invokedynamic 字節碼指令來進行調用。能夠使用JDK中的 javap 工具來反編譯class文件。使用 javap -p 或 javap -c -v 命令來看一看lambda表達式生成的字節碼。大體應該長這樣:spa

private static java.lang.Object lambda$0(java.lang.String);

6)lambda表達式有個限制,那就是隻能引用 final 或 final 局部變量,這就是說不能在lambda內部修改定義在域外的變量。翻譯

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
int factor = 2;
primes.forEach(element -> { factor++; });

Compile time error : "local variables referenced from a lambda expression must be final or effectively final"

另外,只是訪問它而不做修改是能夠的,以下所示:code

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
int factor = 2;
primes.forEach(element -> { System.out.println(factor*element); });

輸出:

1
2
3
4
4
6
10
14

所以,它看起來更像不可變閉包,相似於Python。

相關文章
相關標籤/搜索