你應該知道的Java8新特性之Lambda表示式
highlight: ocean theme: Chinese-red
“我正在參加「掘金·啟航計劃」”
Lambd表示式
Lambda表示式是一個匿名函式,我們可以把 Lambda 表示式理解為是一段可以傳遞的程式碼(將程式碼 像資料一樣進行傳遞)。可以寫出更簡潔、更靈活的程式碼。作為一種更緊湊的程式碼風格,使Java的語言表達能力得到了提升。
1. 格式
'->' :lambda操作符或箭頭操作符\ '->'的左邊: Lambda形參列表(其實就是介面中的抽象方法的形參列表)\ '->'的右邊: Lambda體 (其實就是 重寫的抽象方法的方法體)
2. Lambda表示式的使用
Lambda表示式的使用為了方便理解,分為6種情況介紹,通過內建函式式介面來舉例,也可以對比匿名函式來理解。
- 語法格式一:無參,無返回值,Lambda體只需一條語句
Runnable r2 = ()->{
System.out.println("Test1");
};
- 語法格式二:Lambda需要一個引數,並且無返回值
Consumer<String> con2 = (String s)->{
System.out.println(s);
};
con2.accept("test2");
- 語法格式三:Lambda只需要一個引數時,引數的小括號可以省略,同時省略引數變數型別(型別推斷)
Consumer<String> con2 = s->{
System.out.println(s);
};
con2.accept("test2");
- 語法格式四:Lambda需要兩個引數,並且有返回值
Comparator<Integer> com2 = (Integer o1,Integer o2) -> {
return o1.compareTo(o2);
};
- 語法格式五:當 Lambda 體只有一條語句時,return 與大括號可以省略
Comparator<Integer> com2 = (Integer o1,Integer o2) -> o1.compareTo(o2);
- 語法格式五:資料型別可以省 略,因為可由編譯器推斷得出, 稱為“型別推斷
// 資料型別可以省略,因為可由編 譯器推斷得出, 稱為“型別推斷
Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);
上述 Lambda 表示式中的引數型別都是由編譯器推斷得出的。Lambda 表示式中無需指定型別,程式依然可以編譯,這是因為 javac 根據程式的上下文,在後臺推斷出了引數的型別。Lambda 表示式的型別依賴於上下文環境,是由編譯器推斷出來的。這就是所謂的“型別推斷”
3. 函式式介面
3.1 什麼是函式式介面
只包含一個抽象方法的介面,稱為函式式介面。
你可以通過 Lambda 表示式來建立該介面的物件。(若 Lambda 表示式丟擲一個受檢異常,那麼該異常需要在目標介面的抽象方法上進行宣告)。Lambda表示式也是依賴於函式式介面的。
我們可以在任意函式式介面上使用 @FunctionalInterface 註解, 這樣做可以檢查它是否是一個函式式介面,同時javadoc也會包含一條宣告,說明這個介面是一個函式式介面。
3.2 如何理解函式式介面
1.Java從誕生口起就是一直倡導“一切皆物件”,在Java裡面面向物件(OOP)程式設計是一切。但是隨著python、 scala等語言的興起和新技術的挑戰,Java不得不做出調整以便支援更加廣泛的技術要求,也即Java不但可以支援OOP還可以支援OOF(面向函式程式設計)
2.在函數語言程式設計語言當中,函式被當做一等公民對待。在將函式作為一等公民的程式語言中,Lambda表示式的型別是函式。但是在Java8中,有所不同。在Java8中,Lambda表示式是物件,而不是函式,它們必須依附於一類特別的物件型別-函式式介面。
3.簡單的說,在Java8中,Lambda表示式就是一個函式式介面的例項。這就是Lambda表示式和函式式介面的關係。也就是說,只要一少物件是函式式介面的例項,那麼該物件就可以用Lambda表示式來表示。
所以以前用匿名實現類表示的現在都可以用Lambda表示式來寫。
3.3 自定義函式式介面
```
/*
這個接口裡只能寫一個方法,寫多個方法註解會爆紅,註解的作用是驗證該介面是否是函式介面
若果不寫該註解,並且介面只有一個方法則該介面也是函式式介面
/
@FunctionalInterface
public interface MyInterface {
void method();
}
//泛型寫法
@FunctionalInterface
public interface MyInterface
3.4 Java 內建四大核心函式式介面
| 函式式介面 | 引數型別 | 返回型別 | 用途 |
| ------------------- | ---- | ------- | ------------------------------------------------------- |
| Consumer
舉兩個簡單的例子
```
public void test4(){
Consume(500, new Consumer
public static void Consume(int money, Consumer
public void test5(){
List<String> list = Arrays.asList("sss","rrr","yyyyy","ssdasds","sd");
list = predit(list, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()>3;
}
});
System.out.println(list.toString());
//lambda表示式寫法
List<String> list1 = Arrays.asList("12","13","14","15","16","17");
list1 = predit(list1,i->Integer.parseInt(i)>14);
System.out.println(list1.toString());
}
public static List<String> predit(List<String> strings, Predicate<String> predicate){
List<String> list = new ArrayList<>();
for (String s:strings){
if (predicate.test(s)){
list.add(s);
}
}
return list;
}
下篇預告:Stream常用的API,歡迎繼續交流學習