Java8有哪些新特性?Lambda的詳細(xì)分析

Java8有哪些新特性?Lambda的詳細(xì)分析

深圳達(dá)內(nèi)教育      2022-03-24 17:50:01     9

Java8有哪些新特性?Lambda的詳細(xì)分析,為什么要Lambda#Java8應(yīng)該是目前最大的一次更新了,更新后我們迎來(lái)了很多新特性,其中便包括Lambda表達(dá)式,函數(shù)式編程的思想正式

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹

為什么要Lambda#

Java8應(yīng)該是目前最大的一次更新了,更新后我們迎來(lái)了很多新特性,其中便包括Lambda表達(dá)式,函數(shù)式編程的思想正式進(jìn)入Java,讓我們看一個(gè)經(jīng)典案例。

例1按照兩個(gè)人的年齡排序的功能#

采用匿名內(nèi)部類已經(jīng)算簡(jiǎn)介了,如果專門用一個(gè)類去實(shí)現(xiàn)Comparator再new出來(lái)就更煩了,過去的寫法:

Copy//?已經(jīng)創(chuàng)建好了三個(gè)Person實(shí)例List<Person>?people?=?Arrays.asList(person1,?person2,?person3);Collections.sort(people,?new?Comparator<Person>()?{????@Override????public?int?compare(Person?o1,?Person?o2)?{????????return?o1.getAge().compareTo(o2.getAge());????}});

Lambda版本寫法:

CopyCollections.sort(people,(p1,p2)-&gt;p1.getAge().compareTo(p2.getAge()));

還有更簡(jiǎn)潔的方法引用寫法:

CopyCollections.sort(people,Comparator.comparing(Person::getAge));

是不是真的短真的易讀,語(yǔ)法糖真的甜!已經(jīng)9102年了,函數(shù)式編程被提到的越來(lái)越多,深諳照貓畫虎已經(jīng)行不通了,而且函數(shù)式編程和設(shè)計(jì)模式的碰撞也很多,真的有必要了解下相關(guān)概念

哪里用Lambda#

行為參數(shù)化#

函數(shù)式編程是一種思想,核心是行為參數(shù)化,把一段代碼像值一樣傳遞給方法,傳入不同的代碼實(shí)現(xiàn)不同的功能

這是不是很像策略模式以及模板模式?如例1所示,不需要大量的套路代碼了,也不需要把代碼寫到一個(gè)類中然后新建實(shí)例對(duì)象最后把實(shí)例對(duì)象傳遞

函數(shù)式接口#

函數(shù)式接口就是只定義一個(gè)抽象方法的接口來(lái)表示行為,抽象方法不允許拋出受檢異常,Java8接口可以有default方法了,函數(shù)式接口是允許有default方法的

Lambda表達(dá)式看上去確實(shí)很有吸引力,我能在任何地方都使用么?答案是不能的,我們只能通過Lambda表達(dá)式把代碼傳到函數(shù)式接口中,拿例1中的Comparator接口來(lái)看

Copy FunctionalInterfacepublic interface Comparator&lt;T&gt;{int compare(T o1,T o2);}

Comparator接口只有compare一個(gè)抽象方法,Java8特意給它加了注解告訴我們這就是個(gè)函數(shù)式接口,其實(shí)也很好理解,我們沒有創(chuàng)建任何實(shí)例,只傳了一串代碼,如果Comparator有兩個(gè)抽象方法,編譯器怎么知道我們實(shí)現(xiàn)的是compare方法呢

怎么用Lambda#

上面都是說的函數(shù)式編程,那么什么是Lambda

Lambda就是匿名的行為參數(shù)化的一種語(yǔ)法實(shí)現(xiàn),它沒有名稱,但它有參數(shù)列表、函數(shù)主體、返回類型,可能還有一個(gè)可以拋出的異常列表

語(yǔ)法#

(parameters)-&gt;expression默認(rèn)Return的,expression只能是一句代碼

(parameters)-&gt;{statements;}沒有默認(rèn)Retrun,就相當(dāng)于Comparator.compare(statements;),statements可以是好多行

tips:如果statements很長(zhǎng),那么我們就不應(yīng)該用Lambda,而應(yīng)該單獨(dú)實(shí)現(xiàn)一個(gè)方法,然后使用方法引用這樣可讀性更好,繼續(xù)例1

Copy//?比如說在MyUtils類下寫個(gè)方法,故意加長(zhǎng)public?static?Integer?sortPersonByName(Person?person1,?Person?person2)?{????Integer?age1?=?person1.getAge();????Integer?age2?=?person2.getAge();????return?age1.compareTo(age2);}//?又用到了方法引用,我們可以把方法引用當(dāng)作一種便于閱讀的語(yǔ)法糖,功能也是傳遞代碼Collections.sort(people,?MyUtils::sortPersonByAge);

憑什么Lambda#

在使用Lambda的時(shí)候我們沒有任何類型聲明就能工作這是怎么做到的呢?

函數(shù)描述符#

函數(shù)式接口的抽象方法的簽名基本上就是Lambda表達(dá)式的簽名。我們將這種抽象方法叫作函數(shù)描述符

Comparator.compare的簽名

Copyint compare(T o1,T o2);

這個(gè)函數(shù)式接口的簽名就可以描述成需要兩個(gè)相同類型的變量,然后返回int

(T,T)-&gt;int

Lambda的簽名

Copy(p1,p2)-&gt;p1.getAge().compareTo(p2.getAge())//這是易讀的寫法,我們也可以寫成方便說明(Person p1,Person p2)-&gt;p1.getAge().compareTo(p2.getAge())

可以描述成需要兩個(gè)Person變量,然后compareTo方法返回int

(Person,Person)-&gt;int

編譯器會(huì)做類型推斷和類型檢查,發(fā)現(xiàn)兩個(gè)簽名匹配,我們的Lambda表達(dá)式就可以順利執(zhí)行了

tips:Lambda主體是語(yǔ)句表達(dá)式的時(shí)候(parameters)-&gt;expression,盡管expression返回可能不是void,但是也是兼容T-&gt;void簽名的

進(jìn)階#

新增函數(shù)式接口#

除了Runnable,Comparator等常用函數(shù)式接口,為了推動(dòng)函數(shù)式編程,Java8又在java.util.function包下為我們提供了大量好用的函數(shù)式,因?yàn)榛緮?shù)據(jù)類型不能抽象成對(duì)象,所以可以看到有大量Double,Int,Long前綴的接口,我們只看比較核心的:

接口名抽象方法描述符Predicateboolean test(T t)T-&gt;booleanBiPredicate&lt;T,U&gt;test(T t,U u)(T,U)-&gt;booleanConsumervoid accept(T t)T-&gt;voidBiConsumer&lt;T,U&gt;void accept(T t,U u)(T,U)-&gt;voidFunction&lt;T,R&gt;R apply(T t)T-&gt;RBiFunction&lt;T,U,R&gt;R apply(T t,U u)(T,U)-&gt;RSupplierT get()void-&gt;T

tips:Predicate這種對(duì)給定內(nèi)容做判斷返回boolean值,我們叫做謂詞

復(fù)合Lambda#

令人驚喜的是,java8提供的函數(shù)式接口還有許多好用的default方法,可以讓我們把多個(gè)Lambda復(fù)合起來(lái),組成流水線。拿用的比較多的Function接口舉例,我們要寫一封郵件,我們關(guān)注的是信的內(nèi)容

CopyFunction<String,?String>?writeEmailHeader?=?text?->?"Hi?,"?+?"n"?+?text;Function<String,?String>?writeEmailText?=?text?->?text?+?"n";Function<String,?String>?writeEmailFooter?=?text?->?text?+?"BRs"?+?"n"?+?"Chen";Function<String,?String>?writeEmail?=?writeEmailHeader.andThen(writeEmailText).andThen(writeEmailFooter);System.out.println(writeEmail.apply("I?will?take?half?day?sick?leave?today"));

以上就是深圳達(dá)內(nèi)教育java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java8有哪些新特性?Lambda的詳細(xì)分析”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。