java8-Lambda表達式
點擊上方藍色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達
? 作者?|??Jame
來源 |? urlify.cn/77Rz2e
Lambd
lambda表達式是java8的新特性,可以使用函數(shù)式接口替換掉原來的匿名內(nèi)部類
lambda的本質(zhì)就是引用一個已經(jīng)具體實現(xiàn)的方法來完成對函數(shù)式接口抽象方法的具體實現(xiàn)
例如現(xiàn)在有一個接口,里面只有一個求和方法
public?interface?Mylambda?{
????int?sum(int?a,int?b);
}
我們現(xiàn)在想要使用這個方法,有三種方式
創(chuàng)建一個類實現(xiàn)這個接口
匿名內(nèi)部類
使用lambda函數(shù)式接口
第一種方法就不說了,來看使用匿名內(nèi)部類
Mylambda?myLambda=new?Mylambda()?{
????@Override
????public?int?sum(int?a,?int?b)?{
????????return?a+b;
????}
};
然后調(diào)用myLambda的sum方法可以做到求和的操作
再來看看lambda
Mylambda?myLambda=(int?a,int?b)->{
????return?a+b;
};
()->{} 什么意思呢? 我們來看看lambda是如何使用的
()?里面是傳入的參數(shù)
{}?里面為方法體具體操作
需要注意的點
lambda只能用于只有一個方法的接口
最好在接口上添加注解@FunctionalInterface來表明這是一個函數(shù)式接口
參數(shù)類型因為已經(jīng)在接口中定義,那么傳入?yún)?shù)時可以不用寫參數(shù)類型,要么參數(shù)都寫參數(shù)類型,要不然都不寫參數(shù)類型
參數(shù)的數(shù)量,類型,順序必須和接口中一致
那么lambda就這些嗎? 當(dāng)然不是,還可以簡化以及拆分方法
簡化
如果方法體中就只有一條return語句,例如上面sum方法中,那么在lambda表達式中可以省略大括號以及return
public?static?void?main(String[]?args)?{
????Mylambda?mylambda?=?(a,b)?->?a?+?b;
}
如果參數(shù)只有一個,可以省略小括號
例如下面這個接口,我們并沒有做任何操作,只是將傳入?yún)?shù)原封不動返回,只是為了學(xué)習(xí)使用
@FunctionalInterface
public?interface?MyLambda2?{
????int?print(int?i);
}
使用
public?static?void?main(String[]?args)?{
????MyLambda2?myLambda2=?i?->?i;
}
是不是看的有點蒙呢,不簡化就是
MyLambda2?myLambda2=?(i)?->?{
????return?i;
};
因為參數(shù)只有一個,而且返回值也只有一條return語句,所以省略了傳入?yún)?shù)的小括號以及方法體的大括號和return關(guān)鍵字
這里也有個需要注意的點 : 方法體的大括號和return語句要么都省略,不能只省略一個
如果方法中僅僅想返回一個對象,不做任何其他操作,還可以簡化
//接口============
@FunctionalInterface
public?interface?MyLambda2?{
????User?getUser();
}
//使用,未簡化前===========
public?static?void?main(String[]?args)?{
????MyLambda2?myLambda=()->{
????????return??new?User();
????};
}
//再根據(jù)參數(shù)和方法體簡化=====
public?static?void?main(String[]?args)?{
????MyLambda2?myLambda2=()->new?User();
}
//使用,簡化后
public?static?void?main(String[]?args)?{
????MyLambda2?myLambda=User::new;
}
上面兩個簡化估計都可以看懂,但是最后一個User::new?估計有點蒙,什么意思呢?
在開頭就講過?lambda的本質(zhì)就是引用一個已經(jīng)具體實現(xiàn)的方法來完成對函數(shù)式接口抽象方法的具體實現(xiàn)
而lambda創(chuàng)建User對象說白了就是調(diào)用User的構(gòu)造方法,而lambda調(diào)用對象的構(gòu)造方法的語法就是?類型::new也就是上面寫的User::new
那么如果想通過lambda調(diào)用對象的有參構(gòu)造呢?
很遺憾,不能通過這種方式來調(diào)用對象的有參構(gòu)造,如果想通過lambda調(diào)用,我們可以稍微簡化為下面這種
//接口========
@FunctionalInterface
public?interface?MyLambda2?{
????User?getUser(String?name,int?age);
}
//測試=============
public?static?void?main(String[]?args)?{
????MyLambda2?myLambda2=(name,age)->new?User();
}
拆分
那么如果一個方法我們經(jīng)常使用該怎么辦呢,難道每次都去復(fù)制原來的lambda表達式嗎?
可以將常用的方法單獨拆分出來,每次lambda表達式去調(diào)用這個方法即可
我們以上面的sum接口為例 :
//接口===================
@FunctionalInterface
public?interface?Mylambda?{
????int?sum(int?a,int?b);
}
//測試==================
public?static?void?main(String[]?args)?{
????Mylambda?mylambda?=?(a,b)->?doSum(a,b);
????int?sum?=?mylambda.sum(2,?5);
}
//抽取出的方法(?注意是靜態(tài)調(diào)用靜態(tài),如果是普通方法需要創(chuàng)建對象?)===============
public?static?int?doSum(int?a,int?b){
????return?a+b;
}
我們將求和的操作單獨拆分為一個方法,每次使用時只需要調(diào)用這個方法即可
() -> xxx();
也就是說lambda不僅可以直接寫方法具體細節(jié),也可以調(diào)用其他方法,需要注意的時調(diào)用的方法返回值必須和接口定義返回值一致
當(dāng)然,調(diào)用拆分的方法也可以簡化,使用方法如下
靜態(tài)類 類名::方法
非靜態(tài) 對象::方法
對于靜態(tài)的拆分方法
//接口=======
@FunctionalInterface
public?interface?Mylambda?{
????int?sum(int?a,int?b);
}
//測試類名為Test=========
public?static?void?main(String[]?args)?{
????Mylambda?myLambda=Test::doSum;
}
//拆分的方法========
public?static?int?doSum(int?a,int?b){
????return?a+b;
}
對于非靜態(tài)的拆分方法
//接口=======
@FunctionalInterface
public?interface?Mylambda?{
????int?sum(int?a,int?b);
}
//測試類名為Test=========
public?static?void?main(String[]?args)?{
????Test?test?=?new?Test();
????Mylambda?myLambda=test::doSum;
}
//拆分的方法========
public?static?int?doSum(int?a,int?b){
????return?a+b;
}
兩者區(qū)別僅僅是在于對象::方法和類::方法,因為非靜態(tài)類需要創(chuàng)建出對象才可以調(diào)用方法
當(dāng)使用簡化后的調(diào)用方法那么會自動匹配參數(shù)類型,數(shù)量和順序,所以更加要嚴謹仔細,確保參數(shù)一一對應(yīng)
再說一遍吧,lambda的本質(zhì)就是引用一個已經(jīng)具體實現(xiàn)的方法來完成對函數(shù)式接口抽象方法的具體實現(xiàn),那么現(xiàn)在再來看這句話是不是清楚很多呢
本文僅個人理解,如果有不對的地方歡迎評論指出或私信,謝謝?(?>?)?
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
???

?長按上方微信二維碼?2 秒
感謝點贊支持下哈?
