最通俗易懂的講解:lambda表達(dá)式

Java8發(fā)布已經(jīng)有一段時(shí)間了簸呈,這次發(fā)布的改動(dòng)比較大额港,很多人將這次改動(dòng)與Java5的升級(jí)相提并論样屠。Java8其中一個(gè)很重要的新特性就是lambda表達(dá)式,允許我們將行為傳到函數(shù)中蛹磺。想想看粟瞬,在Java8 之前我們想要將行為傳入函數(shù),僅有的選擇就是匿名內(nèi)部類萤捆。

Java8發(fā)布以后裙品,lambda表達(dá)式將大量替代匿名內(nèi)部類的使用,簡(jiǎn)化代碼的同時(shí)俗或,更突出了原來(lái)匿名內(nèi)部類中最重要的那部分包含真正邏輯的代碼市怎。尤其是對(duì)于做數(shù)據(jù)的同學(xué)來(lái)說(shuō),當(dāng)習(xí)慣使用類似scala之類的函數(shù)式編程語(yǔ)言以后辛慰,體會(huì)將更加深刻∏常現(xiàn)在我們就來(lái)看看Java8中l(wèi)ambda表達(dá)式的一些常見寫法。

lambda體中調(diào)用方法的參數(shù)列表和返回值類型,要和函數(shù)式接口中抽象方法的參數(shù)列表和返回值類型保持一致驰弄。

一麻汰、替代匿名內(nèi)部類

lambda表達(dá)式用的最多的場(chǎng)合就是替代匿名內(nèi)部類,實(shí)現(xiàn)Runnable接口是匿名內(nèi)部類的經(jīng)典例子戚篙。lambda表達(dá)式的功能相當(dāng)強(qiáng)大五鲫,用()->就可以代替整個(gè)匿名內(nèi)部類!

packageOSChina.Lambda;

importorg.junit.Test;

importjava.util.Comparator;

importjava.util.function.Consumer;

importjava.util.function.Function;

importjava.util.function.Predicate;

importjava.util.function.Supplier;

publicclassTest1{

publicstaticvoidmain(String[]?args){

Runnable?runnable?=newRunnable()?{

@Override

publicvoidrun(){

System.out.println("普通岔擂,線程啟動(dòng)");

}

};

runnable.run();

test2();

test3();

test4();

test5();

}

//無(wú)參數(shù)位喂,無(wú)返回值

publicstaticvoidtest2(){

//“->”左邊只有一個(gè)小括號(hào),表示無(wú)參數(shù)乱灵,右邊是Lambda體(就相當(dāng)于實(shí)現(xiàn)了匿名內(nèi)部類里面的方法了塑崖,(即就是一個(gè)可用的接口實(shí)現(xiàn)類了。))

Runnable?runnable?=?()->System.out.println("Lambda?表達(dá)式方式痛倚,線程啟動(dòng)");

runnable.run();

}

//有一個(gè)參數(shù)规婆,并且無(wú)返回值

publicstaticvoidtest3(){

//這個(gè)e就代表所實(shí)現(xiàn)的接口的方法的參數(shù),

Consumer?consumer?=?e->System.out.println("Lambda?表達(dá)式方式蝉稳,"+e);

consumer.accept("傳入?yún)?shù)");

}

//有兩個(gè)以上的參數(shù)聋呢,有返回值,并且?Lambda?體中有多條語(yǔ)句

publicstaticvoidtest4(){

//Lambda 體中有多條語(yǔ)句颠区,記得要用大括號(hào)括起來(lái)

Comparator?com?=?(x,?y)?->?{

System.out.println("函數(shù)式接口");

returnInteger.compare(x,?y);

};

intcompare?=?com.compare(100,244);

System.out.println("有兩個(gè)以上的參數(shù),有返回值,"+compare);

}

//若?Lambda?體中只有一條語(yǔ)句通铲,?return?和?大括號(hào)都可以省略不寫

publicstaticvoidtest5(){

//Comparator?com?=?(x,?y)?->?Integer.compare(100,?244);

System.out.println("若?Lambda?體中只有一條語(yǔ)句毕莱,?return?和?大括號(hào)都可以省略不寫,"+Integer.compare(100,244));

}

}

二、Java8四大內(nèi)置函數(shù)式接口

如果使用lambda還要自己寫一個(gè)接口的話太麻煩颅夺,所以Java自己提供了一些接口:

1朋截、Consumer 消費(fèi)性接口:void accept(T t);

//有一個(gè)參數(shù)吧黄,并且無(wú)返回值

publicstaticvoidtest3(){

//這個(gè)e就代表所實(shí)現(xiàn)的接口的方法的參數(shù)部服,

Consumer?consumer?=?e->System.out.println("Lambda?表達(dá)式方式,"+e);

consumer.accept("傳入?yún)?shù)");

}

2拗慨、Supplier供給型接口:T get();

package?OSChina.Lambda;

importjava.util.ArrayList;

importjava.util.function.Supplier;

publicclassTest2{

publicstaticvoidmain(String[]?args){

ArrayList?res?=?getNumList(10,()->(int)(Math.random()*100));

System.out.println(res);

}

publicstaticArrayList?getNumList(intnum,?Supplier?sup){

ArrayListlist=newArrayList<>();

for(inti?=0;?i?<?num;?i++)?{

Integer?e?=?sup.get();

list.add(e);

}

returnlist;

}

}

3廓八、Function 函數(shù)式接口:R apply(T t);

packageOSChina.Lambda;

importjava.util.function.Function;

publicclassTest2{

publicstatic?void?main(String[]?args)?{

String?newStr?=?strHandler("abc",(str)->str.toUpperCase());

System.out.println(newStr);

newStr?=?strHandler("??abc??",(str)->str.trim());

System.out.println(newStr);

}

publicstatic?String?strHandler(String?str,?Functionfun){

returnfun.apply(str);

}

}

4、Predicate 斷言式接口:boolean test(T t);

判斷一些字符串?dāng)?shù)組判斷長(zhǎng)度>2的字符串:

package?OSChina.Lambda;

importjava.util.ArrayList;

importjava.util.Arrays;

importjava.util.List;

importjava.util.function.Predicate;

publicclassTest2{

publicstaticvoidmain(String[]?args)?{

List?list?=?Arrays.asList("hello","jiangshuying","lambda","www","ok","q");

List?ret?=?filterStr(list,(str)->str.length()>2);

System.out.println(ret);

}

publicstaticList?filterStr(List?list,?Predicate?pre){

ArrayList?arrayList?=newArrayList<>();

for(Stringstr:list){

if(pre.test(str))?{

arrayList.add(str);

}

}

returnarrayList;

}

}

三赵抢、方法引用與構(gòu)造器引用

要求:實(shí)現(xiàn)抽象方法的參數(shù)列表和返回值類型剧蹂,必須與方法引用的方法的參數(shù)列表和返回值類型保持一致!

方法引用:使用操作符“::”將類與方法分隔開來(lái)烦却。

對(duì)象::實(shí)例方法名

類::靜態(tài)方法名

類::實(shí)例方法名

舉個(gè)例子:

publicstaticvoidtest9(){

Comparator?comparator?=?(x,y)->Integer.compare(x,y);

Comparator?comparator1?=?Integer::compare;

intcompare?=?comparator.compare(1,2);

intcompare1?=?comparator1.compare(1,2);

System.out.println("compare:"+compare);

System.out.println("compare1:"+compare1);

}

四宠叼、lambda表達(dá)式的一些常見用法

1、使用lambda表達(dá)式對(duì)集合進(jìn)行迭代

package?OSChina.Lambda;

importjava.util.Arrays;

importjava.util.List;

publicclassTest3{

publicstaticvoidmain(String[]?args){

Listlist=?Arrays.asList("java","c#","javascript");

//before?java8

for(String?str:list){

System.out.println("before?java8,"+str);

}

//after?java8

list.forEach(x->?System.out.println("after?java8,"+x));

}

}

2其爵、用lambda表達(dá)式實(shí)現(xiàn)map

map函數(shù)可以說(shuō)是函數(shù)式編程里最重要的一個(gè)方法了冒冬。map的作用是將一個(gè)對(duì)象變換為另外一個(gè)伸蚯。在我們的例子中,就是通過(guò)map方法將cost增加了0,05倍的大小然后輸出简烤。

package?OSChina.Lambda;

importjava.util.Arrays;

importjava.util.List;

publicclassTest3{

publicstaticvoidmain(String[]?args){

Listlist=?Arrays.asList(10.0,20.0,30.0);

list.stream().map(x->x+x*0.05).forEach(x->?System.out.println(x));

}

}

3剂邮、用lambda表達(dá)式實(shí)現(xiàn)map與reduce

既然提到了map,又怎能不提到reduce乐埠。reduce與map一樣抗斤,也是函數(shù)式編程里最重要的幾個(gè)方法之一,map的作用是將一個(gè)對(duì)象變?yōu)榱硗庖粋€(gè)丈咐,而reduce實(shí)現(xiàn)的則是將所有值合并為一個(gè)瑞眼,請(qǐng)看:

package?OSChina.Lambda;

importjava.util.Arrays;

importjava.util.List;

publicclassTest3{

publicstaticvoidmain(String[]?args){

//before?java8

List?cost?=?Arrays.asList(10.0,20.0,30.0);

doublesum?=0;

for(doubleeach:cost)?{

each?+=?each?*0.05;

sum?+=?each;

}

System.out.println("before?java8,"+sum);

//after?java8

Listlist=?Arrays.asList(10.0,20.0,30.0);

doublesum2?=list.stream().map(x->x+x*0.05).reduce((sum1,x)->sum1+x).get();

System.out.println("after?java8,"+sum2);

}

}

相信用map+reduce+lambda表達(dá)式的寫法高出不止一個(gè)level。

4棵逊、filter操作

filter也是我們經(jīng)常使用的一個(gè)操作伤疙。在操作集合的時(shí)候,經(jīng)常需要從原始的集合中過(guò)濾掉一部分元素辆影。

packageOSChina.Lambda;

importjava.util.Arrays;

importjava.util.List;

importjava.util.stream.Collectors;

publicclassTest3{

publicstaticvoidmain(String[]?args){

List?cost?=?Arrays.asList(10.0,20.0,30.0,40.0);

List?filteredCost?=?cost.stream().filter(x?->?x?>25.0).collect(Collectors.toList());

filteredCost.forEach(x?->?System.out.println(x));

}

}

5徒像、與函數(shù)式接口Predicate配合

除了在語(yǔ)言層面支持函數(shù)式編程風(fēng)格,Java 8也添加了一個(gè)包蛙讥,叫做java.util.function锯蛀。它包含了很多類,用來(lái)支持Java的函數(shù)式編程次慢。

其中一個(gè)便是Predicate旁涤,使用java.util.function.Predicate函數(shù)式接口以及l(fā)ambda表達(dá)式,可以向API方法添加邏輯迫像,用更少的代碼支持更多的動(dòng)態(tài)行為劈愚。Predicate接口非常適用于做過(guò)濾。

package?OSChina.Lambda;

import?java.lang.reflect.Array;

import?java.util.Arrays;

import?java.util.List;

import?java.util.function.Predicate;

publicclassTest4{

publicstaticvoid?filterTest(List?languages,?Predicate?condition)?{

languages.stream().filter(x?->?condition.test(x)).forEach(x?->?System.out.println(x?+"?"));

}

publicstaticvoid?main(String[]?args)?{

List?languages?=?Arrays.asList("Java","Python","scala","Shell","R");

filterTest(languages,x->x.startsWith("J"));//Java?

filterTest(languages,x?->?x.endsWith("a"));//Java,scala?

filterTest(languages,x?->?true);//Java,Python,scala,Shell,R

filterTest(languages,x?->?false);//

filterTest(languages,x?->?x.length()?>4);//Python,scala,Shell,

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闻妓,一起剝皮案震驚了整個(gè)濱河市菌羽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌由缆,老刑警劉巖注祖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異均唉,居然都是意外死亡氓轰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門浸卦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)署鸡,“玉大人,你說(shuō)我怎么就攤上這事⊙デ欤” “怎么了时捌?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)炉抒。 經(jīng)常有香客問我奢讨,道長(zhǎng),這世上最難降的妖魔是什么焰薄? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任拿诸,我火速辦了婚禮,結(jié)果婚禮上塞茅,老公的妹妹穿的比我還像新娘亩码。我一直安慰自己,他們只是感情好野瘦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布描沟。 她就那樣靜靜地躺著,像睡著了一般鞭光。 火紅的嫁衣襯著肌膚如雪吏廉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天惰许,我揣著相機(jī)與錄音席覆,去河邊找鬼。 笑死汹买,一個(gè)胖子當(dāng)著我的面吹牛娜睛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卦睹,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼方库!你這毒婦竟也來(lái)了结序?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纵潦,失蹤者是張志新(化名)和其女友劉穎徐鹤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邀层,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡返敬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寥院。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劲赠。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凛澎,到底是詐尸還是另有隱情霹肝,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布塑煎,位于F島的核電站沫换,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏最铁。R本人自食惡果不足惜讯赏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冷尉。 院中可真熱鬧漱挎,春花似錦、人聲如沸网严。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)震束。三九已至怜庸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垢村,已是汗流浹背割疾。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘉栓,地道東北人宏榕。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像侵佃,于是被迫代替她去往敵國(guó)和親麻昼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言:Java 8 已經(jīng)發(fā)布很久了馋辈,很多報(bào)道表明Java 8 是一次重大的版本升級(jí)抚芦。在Java Code Geek...
    糖寶_閱讀 1,322評(píng)論 1 1
  • 原鏈接:http://www.cnblogs.com/langtianya/p/3757993.html JDK各...
    把愛放下會(huì)走更遠(yuǎn)閱讀 1,112評(píng)論 0 10
  • 參考ImportNew - lemeilleur 翻譯自javarevisited 用例1、用lambda表達(dá)式實(shí)...
    mulinsentt閱讀 562評(píng)論 0 1
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,696評(píng)論 0 3
  • 二婆(母親的二嬸)家后院有一棵香杏樹迈螟,這是一棵異于普通的杏樹叉抡,它的果仁不是苦苦的那種,嚼起來(lái)清香四溢答毫,越吃越想吃褥民。...
    寶天曼風(fēng)景閱讀 735評(píng)論 0 0