被公司打發(fā)去做小程序啦,剛剛還在寫Android,淚奔
Lambda 表達(dá)式
編程中提到的 Lambda 表達(dá)式,通常是在需要一個函數(shù),但是又不想費神去命名一個函數(shù)的場合下使用,也就是指匿名函數(shù)。
Lambda 允許我們把行為傳到函數(shù)里。之前把行為傳到函數(shù)里我們采用的是匿名內(nèi)部類,該方法導(dǎo)致行為最重要的方法夾雜在中間,不夠突出,詳見舉例中代碼。
//以前點擊事件,使用了匿名內(nèi)部類
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_LONG).show();
}
});
//新款Lambda 表達(dá)式,大家可以比較下上下的不同之處
mButton.setOnClickListener(view -> Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_LONG).show());
因此Lambda 表達(dá)式可以理解為簡潔地表示可傳遞的匿名函數(shù)的一種方式:它沒有名稱,但它有參數(shù)列表、函數(shù)主體、返回類型,可能還有一個可以拋出的異常列表。
代碼格式
Lambda 表達(dá)式的基本格式是:() -> {}
有下面三種具體表達(dá):
//(params) -> expression
//接收 x 和 y 這兩個整形參數(shù)并返回它們的和;
(int x, int y) -> x + y
//(params) -> statement
//不接收參數(shù),返回整數(shù) ‘42’;
() -> 42
//(params) -> {statement}
//接收一個字符串并把它打印到控制臺,不返回值。
(String s) -> { System.out.println(s); }
文字解釋
Lambda 表達(dá)式的語法由參數(shù)列表、箭頭符號 -> 和函數(shù)體組成。函數(shù)體既可以是一個表達(dá)式,也可以是一個語句塊:
- 表達(dá)式:表達(dá)式會被執(zhí)行然后返回執(zhí)行結(jié)果。
- 語句塊:語句塊中的語句會被依次執(zhí)行,就像方法中的語句一樣
- return 語句會把控制權(quán)交給匿名方法的調(diào)用者
- break 和 continue 只能在循環(huán)中使用
- 如果函數(shù)體有返回值,那么函數(shù)體內(nèi)部的每一條路徑都必須有返回值
Lambda 表達(dá)式也會經(jīng)常出現(xiàn)在嵌套環(huán)境中,比如說作為方法的參數(shù)。為了使 lambda 表達(dá)式在這些場景下盡可能簡潔,我們?nèi)コ瞬槐匾姆指舴?。不過在某些情況下我們也可以把它分為多行,然后用括號包起來,就像其它普通表達(dá)式一樣。
FileFilter java = (File f) -> f.getName().endsWith("*.java");
String user = doPrivileged(() -> System.getProperty("user.name"));
new Thread(() -> {
connectToService();
sendNotification();
}).start();
具體案例

方法引用(關(guān)鍵字 ::)
簡單來說,方法引用就是 Lambda 表達(dá)式的一種簡寫。當(dāng)你創(chuàng)建一個 Lambda 表達(dá)式時,你創(chuàng)建了一個匿名方法并提供方法體,但你使用方法引用時,你只需要提供已經(jīng)存在的方法的名字,它本身已經(jīng)包含方法體。
做一個簡單的解釋,對集合進(jìn)行排序,使用了Comparator的匿名內(nèi)部類寫法
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(1);
Collections.sort(list,new Comparator<Integer>(){
@Override
public int compare(Integer a, Integer b) {
return a - b;
}
});
}
//用Lambda 進(jìn)行表示
Collections.sort(list, (a, b) -> a - b);
//使用Lamabda 的方法引用,可以讓匿名內(nèi)部類Comparator中方法的兩個參數(shù)和Integer類中compare方法的兩個參數(shù)自動對應(yīng)起來,是不是簡潔明了呢。
Collections.sort(list, Integer::compare);
方法引用的種類(Kinds of method references)
- 靜態(tài)方法引用:ClassName::methodName
- 實例上的實例方法引用:instanceReference::methodName
- 超類上的實例方法引用:super::methodName
- 類型上的實例方法引用:ClassName::methodName
- 構(gòu)造方法引用:Class::new
- 數(shù)組構(gòu)造方法引用:TypeName[]::new
- 對于靜態(tài)方法引用,我們需要在類名和方法名之間加入 :: 分隔符,例如 Integer::sum
使用 Lambda 的好處
- Lambda 表達(dá)式不需要每次都要被實例化,對于 Java 來說,帶來巨大的好處。不像實例化匿名類,對內(nèi)存的影響可以降到最小。
- Lambda 表達(dá)式不需要拷貝變量到它的運行環(huán)境中,從而 Lambda 表達(dá)式被當(dāng)做是一個真正的方法來對待,而不是一個類的實例 。
- 因為是復(fù)制,變量必須聲明為 final 類型,以保證在獲取和使用時不會被改變。Java 使用了優(yōu)雅的方式保證了變量不會被更新,所以我們不用顯式地把變量加上 final 修飾。
- Lambda 表達(dá)式函數(shù)體適合小型 Lambda 表達(dá)式,它消除了 return 關(guān)鍵字,使得語法更加簡潔。
- Lambda 表達(dá)式取代了匿名內(nèi)部類,取消了模板,允許通過函數(shù)式風(fēng)格編寫代碼,使代碼的可讀性更高,如果不想看不懂大佬的代碼的話,趕緊學(xué)起來吧。
參考
http://m.itdecent.cn/p/f569c090ec15
http://m.itdecent.cn/p/4b6a875694f0
http://jp1017.github.io/2015/12/20/jdk1-8%E6%96%B0%E7%89%B9%E6%80%A7%E4%B9%8Blambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%8F%8A%E5%9C%A8Android-Studio%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8/