最近學(xué)到的Lambda表達(dá)式基礎(chǔ)知識(shí)
前言
只有光頭才能變強(qiáng)。
中秋去了躺上海,在外灘上打了個(gè)卡:
外灘緊接著學(xué)了一下Java的函數(shù)式編程,給大家整理了一下,一起學(xué)習(xí)!
一、Lambda用法
之前寫(xiě)Optional這個(gè)類的時(shí)候,簡(jiǎn)單說(shuō)了一下Lambda是怎么用的,這里再跟大家一起回顧一下,Lambda的語(yǔ)法是這樣的:
語(yǔ)法以Lambda語(yǔ)法創(chuàng)建線程和匿名內(nèi)部類創(chuàng)建線程的區(qū)別(顯然代碼少了很多!):
public?static?void?main(String[]?args)?{
????//?用匿名內(nèi)部類的方式來(lái)創(chuàng)建線程
????new?Thread(new?Runnable()?{
????????@Override
????????public?void?run()?{
????????????System.out.println("公眾號(hào):Java3y---關(guān)注我!");
????????}
????});
????//?使用Lambda來(lái)創(chuàng)建線程
????new?Thread(()?->?System.out.println("公眾號(hào):Java3y---關(guān)注我!"));
}
使用Lambda表達(dá)式,實(shí)際就是創(chuàng)建出該接口的實(shí)例對(duì)象。
返回一個(gè)Runnable對(duì)象實(shí)例圖示;Runnable接口來(lái)舉例:
以Runnable接口為例使用Labmda表達(dá)式需要函數(shù)式編程接口,比如在Runnable接口上我們可以看到@FunctionalInterface注解(標(biāo)記著這個(gè)接口只有一個(gè)抽象方法)
函數(shù)式編程接口只有一個(gè)抽象方法1.1 函數(shù)式編程接口
從上面的代碼例子可以看出,我們使用Lambda表達(dá)式創(chuàng)建線程的時(shí)候,并不關(guān)心接口名,方法名,參數(shù)名。我們只關(guān)注他的參數(shù)類型,參數(shù)個(gè)數(shù),返回值。
JDK原生就給我們提供了一些函數(shù)式編程接口方便我們?nèi)ナ褂茫旅媸且恍┏S玫慕涌冢?/p>
常用的函數(shù)式編程接口
簡(jiǎn)單說(shuō)明一下:
表格中的一元接口表示只有一個(gè)入?yún)ⅲ涌诒硎居袃蓚€(gè)入?yún)?/span>
以BiFunction為例
常用的函數(shù)式接口Demo:
//?Consumer?一個(gè)入?yún)ⅲ瑹o(wú)返回值
Consumer?consumer?=?s->?System.out.println(s);
consumer.accept("Java3y");
//?Supplier?無(wú)入?yún)ⅲ蟹祷刂?/span>
Supplier?supplier?=?()?->?"Java4y";
String?s?=?supplier.get();
System.out.println(s);
//.....
使用Lambda時(shí),要記住的就兩點(diǎn):
Lambda返回的是接口的實(shí)例對(duì)象
有沒(méi)有參數(shù)、參數(shù)有多少個(gè)、需不需要有返回值、返回值的類型是什么---->選擇自己合適的函數(shù)式接口
1.2 方法引用
在學(xué)Lambda的時(shí)候,還可能會(huì)發(fā)現(xiàn)一種比較奇怪的寫(xiě)法,例如下面的代碼:
//?方法引用寫(xiě)法
Consumer?consumer?=?System.out::println;
consumer.accept("Java3y");
如果按正常Lambda的寫(xiě)法可能是這樣的:
//?普通的Lambda寫(xiě)法
Consumer?consumer?=?s?->?System.out.println(s);
consumer.accept("Java3y");
顯然使用方法引用比普通的Lambda表達(dá)式又簡(jiǎn)潔了一些。
如果函數(shù)式接口的實(shí)現(xiàn)恰好可以通過(guò)調(diào)用一個(gè)方法來(lái)實(shí)現(xiàn),那么我們可以使用方法引用
函數(shù)式接口的實(shí)現(xiàn)恰好可以通過(guò)調(diào)用一個(gè)方法來(lái)實(shí)現(xiàn)方法引用又分了幾種:
靜態(tài)方法的方法引用
非靜態(tài)方法的方法引用
構(gòu)造函數(shù)的方法引用
方法引用Demo:
public?class?Demo?{
????public?static?void?main(String[]?args)?{
????????//?靜態(tài)方法引用--通過(guò)類名調(diào)用
????????Consumer?consumerStatic?=?Java3y::MyNameStatic;
????????consumerStatic.accept("3y---static");
????????//實(shí)例方法引用--通過(guò)實(shí)例調(diào)用
????????Java3y?java3y?=?new?Java3y();
????????Consumer?consumer?=?java3y::myName;
????????consumer.accept("3y---instance");
????????//?構(gòu)造方法方法引用--無(wú)參數(shù)
????????Supplier?supplier?=?Java3y::new;
????????System.out.println(supplier.get());
????}
}
class?Java3y?{
????//?靜態(tài)方法
????public?static?void?MyNameStatic(String?name)?{
????????System.out.println(name);
????}
????//?實(shí)例方法
????public?void?myName(String?name)?{
????????System.out.println(name);
????}
????//?無(wú)參構(gòu)造方法
????public?Java3y()?{
????}
}
結(jié)果如下:
結(jié)果最后
Lambda雖然代碼看起來(lái)是簡(jiǎn)潔,但是如果復(fù)雜的話還是比較難看明白的。
在學(xué)習(xí)Lambda的時(shí)候,首先我們得知道有哪些常用函數(shù)式編程接口,這些函數(shù)式編程接口的有什么區(qū)別(參數(shù)個(gè)數(shù)、返回值類型)
Lambda表達(dá)式返回的是接口對(duì)象實(shí)例,如果函數(shù)式接口的實(shí)現(xiàn)恰好可以通過(guò)調(diào)用一個(gè)方法來(lái)實(shí)現(xiàn),那么我們可以使用方法引用來(lái)替代Lambda表達(dá)式
最后再完整舉個(gè)例子:
//?Supplier是一個(gè)無(wú)入?yún)Х祷氐闹档暮瘮?shù)式編程接口
//?()?-> new Java3y()這整句Lambda表達(dá)式,返回的是Supplier接口的實(shí)例。從Lambda表達(dá)式可以看出無(wú)參數(shù),帶返回值
Supplier?supplier?=?()?->?new?Java3y();?
//?由于這個(gè)“()?->?new?Java3y()”Lambda表達(dá)式可以通過(guò)調(diào)用一個(gè)方法就實(shí)現(xiàn)了,那么我們可以優(yōu)化成方法引用
Supplier?supplier2?=?Java3y::new; 推薦閱讀:
喜歡我可以給我設(shè)為星標(biāo)哦

好文章,我?在看?

