【java8】Lambda表達(dá)式簡(jiǎn)單介紹

image

開(kāi)始

上大學(xué)的時(shí)候就知道java8肖揣,lambda表達(dá)式帘腹。記得有段時(shí)間在寫(xiě)匿名內(nèi)部類(lèi)的時(shí)候,編譯器會(huì)提示可以使用lambda表達(dá)式進(jìn)行優(yōu)化许饿。雖然對(duì)Java8有一丟丟了解阳欲,但是工作至今還沒(méi)有真正的使用過(guò)java8的東西。于是現(xiàn)在讀了一下《java8實(shí)戰(zhàn)》學(xué)習(xí)了一下,現(xiàn)在先簡(jiǎn)單總結(jié)一下lambda表達(dá)式球化。

了解Lambda表達(dá)式

可以把Lambda表達(dá)式理解為簡(jiǎn)潔地表示可傳遞的匿名函數(shù)的一種方式:它沒(méi)有名稱(chēng)秽晚,但他有參數(shù)列表、函數(shù)主題筒愚、返回類(lèi)型赴蝇。使用Lambda可以讓代碼變得更簡(jiǎn)潔、更靈活巢掺。在以前使用匿名內(nèi)部類(lèi)的地方可以使用Lambda來(lái)進(jìn)行優(yōu)化處理句伶。

Lambda的基本語(yǔ)法是:

(parameters) -> expression

或者是

(parameters) -> { expression; }

以下是五個(gè)Lambda表達(dá)式的示例:

示例1:有一個(gè)String類(lèi)型的參數(shù),并返回一個(gè)int陆淀。表達(dá)式?jīng)]有retuern語(yǔ)句考余,因?yàn)橐呀?jīng)隱含了return。

(String s) -> s.length()

示例2:有個(gè)Apple類(lèi)型的參數(shù)轧苫,并返回一個(gè)boolean楚堤。

(Apple a) -> a.getWeight() > 150;

示例3:有兩個(gè)int類(lèi)型的參數(shù),沒(méi)有返回值含懊。大括號(hào)包圍可以寫(xiě)多行身冬。

(int x, int y) -> {
    System.out.println("Result:");
    System.out.println(x + y);
}

示例4:沒(méi)有參數(shù),有一個(gè)int的返回值岔乔。

() -> 42

示例5:有兩個(gè)Apple的參數(shù)酥筝,有一個(gè)boolean返回值。

(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())

使用場(chǎng)景以及如何使用Lambda表達(dá)式

首先給一個(gè)完整的Lambda的使用示例雏门。

篩選函數(shù):

public static <T> List<T> filter(List<T> list, Predicate<T> p) {
    List<T> result = new ArrayList<>();
    for (T e : list) {
        if (p.test(e)) {
            result.add(e);
        }
    }
    return result;
}

調(diào)用代碼:

List<Apple> redApples = filter(inventory, (Apple apple) -> "red".equals(apple.getColor()));

調(diào)用代碼的第二個(gè)參數(shù)傳入了一段lambda表達(dá)式嘿歌。需要注意的是第二個(gè)參數(shù)的類(lèi)型是Predicate<t style="margin: 0px; padding: 0px;">,這是一個(gè)函數(shù)式接口〗伺洌現(xiàn)在就回答小節(jié)題目中的一個(gè)問(wèn)題了,可以在函數(shù)式接口上使用Lambda表達(dá)式阅束。</t>

函數(shù)式接口

函數(shù)式接口是只定義一個(gè)抽象方法的接口呼胚。 Lambda表達(dá)式允許你直接以?xún)?nèi)聯(lián)的形式為函數(shù)式接口的抽象方法提供實(shí)現(xiàn),并把整個(gè)表達(dá)式作為函數(shù)式接口的實(shí)例息裸。(簡(jiǎn)單說(shuō)來(lái)蝇更,Lambda表達(dá)式是函數(shù)式接口的實(shí)例)。用匿名內(nèi)部類(lèi)也能完成同樣的事情呼盆,但是會(huì)笨重點(diǎn)年扩,這也是Lambda可以做優(yōu)化的一個(gè)點(diǎn)。

像我們平常用Runnable復(fù)合函數(shù)式接口的定義访圃,所以也是一個(gè)函數(shù)式接口厨幻。為了使用方便Java也提供了一些常用的函數(shù)式接口,大家也可以自己定義。關(guān)于函數(shù)式接口后面還會(huì)詳細(xì)介紹况脆。

函數(shù)描述符

函數(shù)描述符要表達(dá)的是一個(gè)抽象方法接受什么樣的參數(shù)饭宾,有什么樣的返回值的一個(gè)概念。例如Runnable接口函數(shù)描述符是什么也不接受什么也返回格了。因?yàn)樗ㄒ坏某橄蠓椒╮un看铆,什么也不接受什么也不返回。

Lambda表達(dá)式可以接受參數(shù)并有返回值盛末,必然就需要這個(gè)Lambda的函數(shù)的簽名(接受參數(shù)和返回值)要和函數(shù)式接口相匹配弹惦。

例如下面代碼,Runnable的簽名是什么都不接受什么都不返回悄但。

public void process(Runnable r) {
    r.run();
}

調(diào)用代碼棠隐,傳入的lambda表達(dá)式的簽名也是什么都不接受,什么都不返回算墨。所以它們可以匹配起來(lái)宵荒。

process(()-> System.out.println("funny新青年"));
小提示:
建議給函數(shù)式接口加@FunctionalInterface的注解净嘀,如果該接口不符合函數(shù)式接口的定義的時(shí)候編譯器將會(huì)報(bào)錯(cuò)报咳。

函數(shù)式接口

首先溫習(xí)下上節(jié)的關(guān)鍵定義。函數(shù)式接口是只定義一個(gè)抽象方法的接口挖藏。 函數(shù)式接口的抽象方法的簽名成為函數(shù)描述符暑刃。

為了適應(yīng)不同的Lambda表達(dá)式,需要有一套能夠描述常見(jiàn)函數(shù)描述符的函數(shù)式接口膜眠。Java Api中已經(jīng)提供了一些常用的岩臣,免的每次使用Lambda表達(dá)式還需要自己定義函數(shù)式接口。

Java8新提供的函數(shù)式接口在java.util.function包下宵膨。具體可以查看java8 api doc(https://docs.oracle.com/javase/8/docs/api/)架谎。

Predicate

java.util.function.Predicate<t style="margin: 0px; padding: 0px;">接口定義了一個(gè)名叫test的抽象方法,他接受泛型T辟躏,返回boolean谷扣。</t>

Consumer

java.util.function.Predicate<t style="margin: 0px; padding: 0px;">接口定義了一個(gè)名叫accept的抽象方法,它接受一個(gè)泛型T的對(duì)象捎琐,沒(méi)有返回会涎。算是消費(fèi)一個(gè)對(duì)象。</t>

Function

java.util.function.Function<t, r="" style="margin: 0px; padding: 0px;">接口定義了一個(gè)名叫apply的抽象方法瑞凑,它接受一個(gè)泛型T的對(duì)象末秃,返回一個(gè)泛型R對(duì)象。是將輸入經(jīng)過(guò)計(jì)算得到一個(gè)輸出接口籽御。</t,>

Supplier

定義了一個(gè)名為get的抽象方法练慕,代表的函數(shù)描述符是() -> T惰匙。

因?yàn)楹瘮?shù)式接口中的泛型只能綁定到引用類(lèi)型,如果想使用基本類(lèi)型可以使用基本類(lèi)型對(duì)應(yīng)的引用類(lèi)型贺待,然后采用自動(dòng)裝箱徽曲,但是這會(huì)導(dǎo)致一些性能損耗。所以Java還給對(duì)應(yīng)的函數(shù)式接口提供了基礎(chǔ)類(lèi)型的特殊處理麸塞。比如給Predicate接口提供了IntPredicate秃臣、LongPredicate、DoublePredicate,分別是傳入int哪工、long奥此、double返回boolean。其他函數(shù)式接口也同樣有這樣的原始類(lèi)型特化處理雁比。

以上提供的函數(shù)式接口僅允許傳入一個(gè)參數(shù)稚虎,為了更靈活一些。java還提供了對(duì)應(yīng)兩個(gè)參數(shù)的函數(shù)式接口有BiPredicate<l, r="" style="margin: 0px; padding: 0px;">偎捎、BiConsumer<t, u="" style="margin: 0px; padding: 0px;">蠢终、BiFunction<t, r="" style="margin: 0px; padding: 0px;">。</t,></t,></l,>

全部的函數(shù)式接口自己去java8 api doc(https://docs.oracle.com/javase/8/docs/api/) 找吧茴她。

方法引用

方法引用可以讓你使用已有的方法實(shí)現(xiàn)Lambda表達(dá)式寻拂,將目標(biāo)引用放在分隔符::之前,方法名放在::后面丈牢。方法引用可以視為僅僅涉及單一方法的Lambda的語(yǔ)法糖祭钉,優(yōu)點(diǎn)是代碼能寫(xiě)的更少,更清晰一點(diǎn)己沛。

那么如何構(gòu)建方法引用呢慌核?方法引用有三類(lèi)。

  1. 指向靜態(tài)方法的方法引用申尼。(例如Integer的parseInt方法垮卓,方法引用可以寫(xiě)作Integer::parseInt,對(duì)用的Lambda表達(dá)式為(String s)-> Integer.parseInt(s))师幕。

  2. 指向任意類(lèi)型方法的方法引用粟按。(Lambda要調(diào)用參數(shù)中的一個(gè)方法,例如String的length方法们衙,方法引用可以寫(xiě)作String::length钾怔,對(duì)應(yīng)的Lambda表達(dá)式為 (String s) -> s.length())碱呼。

  3. 指向現(xiàn)有對(duì)象的實(shí)例方法引用蒙挑。(Lambda要調(diào)用一個(gè)外部的對(duì)象的方法,例如外部有一個(gè)expr對(duì)象愚臀,要調(diào)用他的一個(gè)方法忆蚀,方法應(yīng)用可以寫(xiě)成expr::instanceMethod,對(duì)應(yīng)的Lambda可以寫(xiě)作(args) -> expr.instanceMethod(args)。

構(gòu)造函數(shù)引用

構(gòu)造函數(shù)的引用是方法引用的一個(gè)特殊方法馋袜。

對(duì)于一個(gè)現(xiàn)有的構(gòu)造函數(shù)可以使用類(lèi)名稱(chēng)和new關(guān)鍵字來(lái)創(chuàng)建他的一個(gè)引用:className::new男旗。他的功能與靜態(tài)方法的引用類(lèi)似。

構(gòu)造函數(shù)的引用的返回值肯定是確定的欣鳖。就是className察皇,問(wèn)題在于有幾個(gè)參數(shù)。對(duì)于參數(shù)數(shù)量的不同我們可以選擇不同的簽名泽台。
無(wú)參可以用Supplier什荣,一個(gè)參數(shù)可以用Function,兩個(gè)參數(shù)可以用BiFunction怀酷,三個(gè)四五個(gè)就需要你自己來(lái)實(shí)現(xiàn)一些函數(shù)式接口了稻爬。

復(fù)合Lambda表達(dá)式

java8允許你將簡(jiǎn)單的Lambda表達(dá)式復(fù)合成更復(fù)雜的表達(dá)式。下面講會(huì)比較常用的兩種謂詞復(fù)合和函數(shù)符合蜕依。

謂詞復(fù)合

謂詞接口包含三個(gè)方法:negate桅锄、and和or。你可以重用Predicate來(lái)創(chuàng)建更復(fù)雜的謂詞样眠。

比如你原有一個(gè)謂詞一個(gè)謂詞是從一堆蘋(píng)果中取出紅色的那些∮蚜觯現(xiàn)在想要取出不是紅色的那些,只需要使用negate接口就可以了吹缔。

Predicate<T> notRedApple = redApple.negate();

類(lèi)似的商佑,如果你想得到又紅又大的蘋(píng)果,可以將篩選紅色蘋(píng)果的謂詞和重量更大的蘋(píng)果的謂詞用and連接起來(lái)厢塘。

Predicate<T> notRedApple = redApple.and(a -> a.getWeight > 150);

函數(shù)復(fù)合

你還可以把Function接口所代表的Lambda表達(dá)式組合起來(lái)茶没,有兩個(gè)對(duì)應(yīng)的默認(rèn)方法andThen和compose。

andThen是先執(zhí)行完前面的函數(shù)再執(zhí)行后面的晚碾,compose則相反抓半。例如有兩個(gè)函數(shù),f(x)和g(x)格嘁。f.andThen(g)相當(dāng)于g(f(x))笛求,f.compose(g)相當(dāng)于f(g(x))。

最后

本文內(nèi)容基本是根據(jù)《java8實(shí)現(xiàn)》第三章編寫(xiě)的糕簿,將自己認(rèn)為重要的內(nèi)容拿出來(lái)說(shuō)了一說(shuō)探入。值得一提的是寫(xiě)一篇文章比單純的看書(shū)理解到的內(nèi)容多多了。打完收工懂诗!

image

歡迎關(guān)注~~~
歡迎關(guān)注【Funny 新青年】微信公眾號(hào)蜂嗽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市殃恒,隨后出現(xiàn)的幾起案子植旧,更是在濱河造成了極大的恐慌辱揭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件病附,死亡現(xiàn)場(chǎng)離奇詭異问窃,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)完沪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)域庇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人覆积,你說(shuō)我怎么就攤上這事较剃。” “怎么了技健?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵写穴,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我雌贱,道長(zhǎng)啊送,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任欣孤,我火速辦了婚禮馋没,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘降传。我一直安慰自己篷朵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布婆排。 她就那樣靜靜地躺著声旺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪段只。 梳的紋絲不亂的頭發(fā)上腮猖,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音赞枕,去河邊找鬼澈缺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛炕婶,可吹牛的內(nèi)容都是我干的姐赡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼柠掂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼项滑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起陪踩,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杖们,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后肩狂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體摘完,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年傻谁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孝治。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡审磁,死狀恐怖谈飒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情态蒂,我是刑警寧澤杭措,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站钾恢,受9級(jí)特大地震影響手素,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘩蚪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一泉懦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疹瘦,春花似錦崩哩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至险胰,卻和暖如春吴超,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸯乃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工鲸阻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缨睡。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓鸟悴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親奖年。 傳聞我的和親對(duì)象是個(gè)殘疾皇子细诸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 簡(jiǎn)介 概念 Lambda 表達(dá)式可以理解為簡(jiǎn)潔地表示可傳遞的匿名函數(shù)的一種方式:它沒(méi)有名稱(chēng),但它有參數(shù)列表陋守、函數(shù)主...
    劉滌生閱讀 3,193評(píng)論 5 18
  • 原文鏈接: Lambdas 原文作者: shekhargulati 譯者: leege100 lambda表達(dá)式是...
    忽來(lái)閱讀 6,569評(píng)論 8 129
  • Java8 in action 沒(méi)有共享的可變數(shù)據(jù)震贵,將方法和函數(shù)即代碼傳遞給其他方法的能力就是我們平常所說(shuō)的函數(shù)式...
    鐵牛很鐵閱讀 1,213評(píng)論 1 2
  • 親愛(ài)的媽媽今天好多啦利赋,我真的特別開(kāi)心和滿(mǎn)足???媽媽今天不哼哼了,中午還很棒地跟我們坐飯桌上吃飯? 隨著成績(jī)公布時(shí)...
    璠璠_6a8a閱讀 180評(píng)論 0 1
  • 接觸中國(guó)式眾籌至今猩系,大多做的都是以思考和溝通媚送,推廣理念,同化思想為主寇甸。沒(méi)有勇氣和信心做出實(shí)際發(fā)起行為塘偎。今天有幸與楊...
    7f8515619d98閱讀 279評(píng)論 0 1