1. Lambda 表達(dá)式介紹
Lambda 表達(dá)式為 Java 添加了缺失的 函數(shù)式編程特性,使我們能將函數(shù)當(dāng)作一等公民對待。
在將函數(shù)作為一等公民的語言中,Lambda 表達(dá)式的類型是函數(shù)。而在 Java 中,Lambda 表達(dá)式是對象,他們必須依附于一類特別的對象類型 —— 函數(shù)式接口(FunctionalInterface)。
函數(shù)式接口
- 如果一個接口只有一個抽象方法,那么該接口是一個函數(shù)式接口
- 如果我們在某個接口上聲明了 FunctionalInterface 注解,那么編譯器就會按照函數(shù)式接口的定義來要求該接口
- 如果一個接口只有一個抽象方法,但沒有給該接口聲明 FunctionalInterface 注解,那么編譯器依舊會將該接口看成函數(shù)式接口
Lamdba 表達(dá)式是一種匿名函數(shù);它是沒有聲明的方法,即沒有訪問修飾符、返回值聲明和名字。
Lambda 表達(dá)式的作用是傳遞行為,而不僅僅是值。提升了抽象層次,API 重用性更好,更加靈活。
2. Lambda 表示式基本語法
(arg1, arg2...) -> { body }
(type1 arg1, type2 arg2...) -> { body }
示例:
(int a, int b) -> { return a + b; }(String s) -> System.out.println(s);a -> return a * a;() -> 43;() -> { return 3.14; }
- 一個 Lambda 表達(dá)式可以有零個或多個參數(shù)
- 參數(shù)的類型可以明確聲明,也可以根據(jù)上下文來推斷。比如
(String s)可以省略為(s)- 所有參數(shù)須包含在圓括號內(nèi),參數(shù)之間用逗號相隔。當(dāng)只有一個參數(shù)且其類型可推導(dǎo)時,圓括號可省略,比如
a -> return a * a;- 空圓括號代表參數(shù)集為空。比如
() -> 43;- Lambda 表達(dá)式的主體可包含零條或多條語句。如果 Lambda 表達(dá)式的主體只有一條語句,花括號
{}可省略。匿名函數(shù)的返回值類型與該主體表達(dá)式一致。- 如果 Lambda 表達(dá)式的主體包含一條以上語句,則表達(dá)式必須包含在花括號
{}中(形成代碼塊)。匿名函數(shù)的返回值類型與代碼塊的返回類型一致,若沒有則為空。
3. 方法引用
方法引用(Method References)實(shí)際上是 Lambda 表達(dá)式的一種語法糖。我可以將方法引用看作是一個“函數(shù)指針”(指向一個函數(shù)的指針)。
例如:
list.forEach(item -> System.out.println(item))
可以改為使用方法引用:
list.forEach(System.out::println)
方法引用的四種類型:
- 類名::靜態(tài)方法名
public class Person {
String name;
LocalDate birthday;
public static int compareByAge(Person a,Person b){
return a.birthday.compareTo(b.birthday);
}
}
Arrays.sort(people, Person::compareByAge);
- 對象::實(shí)例方法名
list.forEach(System.out::println)
- 類名::實(shí)例方法名
String[] cities = { "guangdong", "hunan", "hebei", "beijing" };
Arrays.sort(cities, String::compareToIgnoreCase);
- 構(gòu)造方法引用
String::new