真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么掌握J(rèn)ava中的Lambda

本篇內(nèi)容介紹了“怎么掌握J(rèn)ava中的Lambda”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

10年積累的成都網(wǎng)站建設(shè)、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)制作后付款的網(wǎng)站建設(shè)流程,更有盤(pán)錦免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

方法類型

從Java 8起方法就是一等公民了。按照標(biāo)準(zhǔn)的定義,編程語(yǔ)言中的一等公民是一個(gè)具有下列功能的實(shí)體,

可以作為參數(shù)進(jìn)行傳遞,  可以作為方法的返回值  可以賦值給一個(gè)變量.

在Java中,每一個(gè)參數(shù)、返回值或變量都是有類型的,因此每個(gè)一等公民都必須是有類型的。Java中的一種類型可以是以下內(nèi)容之一:

一種內(nèi)建類型 (比如 int 或者 double)  一個(gè)類 (比如ArrayList)  一個(gè)接口 (比如 Iterable)

方法是通過(guò)接口進(jìn)行定義類型的。它們不隱式的實(shí)現(xiàn)特定接口,但是在必要的時(shí)候,如果一個(gè)方法符合一個(gè)接口,那么在編譯期間,Java編譯器會(huì)對(duì)其進(jìn)行隱式的檢查。舉個(gè)例子說(shuō)明:

class LambdaMap {static void oneStringArgumentMethod(String arg) {System.out.println(arg);}}

關(guān)于oneStringArgumentMethod函數(shù)的類型,與之相關(guān)的有:它的的函數(shù)是靜態(tài)的,返回類型是void,它接受一個(gè)String類型的參數(shù)。一個(gè)靜態(tài)函數(shù)符合包含一個(gè)apply函數(shù)的接口,apply函數(shù)的簽名相應(yīng)地符合這個(gè)靜態(tài)函數(shù)的簽名。

oneStringArgumentMethod函數(shù)對(duì)應(yīng)的接口因此必須符合下列標(biāo)準(zhǔn)。

它必須包含一個(gè)名為apply的函數(shù)。  函數(shù)返回類型必須是void。  函數(shù)必須接受一個(gè)String類型可以轉(zhuǎn)換到的對(duì)象的參數(shù)。

在符合這個(gè)標(biāo)準(zhǔn)的接口之中,下面的這個(gè)是最明確的:

interface OneStringArgumentInterface {void apply(String arg);}

利用這個(gè)接口,函數(shù)可以分配給一個(gè)變量:

OneStringArgumentInterface meth = LambdaMap::oneStringArgumentMethod;

用這種方法使用接口作為類型,函數(shù)可以借此被分配給變量,傳遞參數(shù)并且從函數(shù)返回:

static OneStringArgumentInterface getWriter() {return LambdaMap::oneStringArgumentMethod;}static void write(OneStringArgumentInterface writer, String msg) {writer.apply(msg);}

最終函數(shù)是一等公民。

泛型函數(shù)類型

就像使用集合一樣,泛型為函數(shù)類型增加了大量的功能和靈活性。實(shí)現(xiàn)功能上的算法而不考慮類型相關(guān)信息,泛型函數(shù)類型使其變?yōu)榭赡?。在?duì)map函數(shù)的實(shí)現(xiàn)中,會(huì)在下面用到這種功能。

在這提供的OneStringArgumentInterface一個(gè)泛型版本:

interface OneArgumentInterface {void apply(T arg);}

OneStringArgumentInterface函數(shù)可以被分配給它:

OneArgumentInterface meth = LambdaMap::oneStringArgumentMethod;

通過(guò)使用泛型函數(shù)類型,它現(xiàn)在可以以一種通用的方法實(shí)現(xiàn)算法,就像它在集合中使用的一樣:

static void applyArgument(OneArgumentInterface meth, T arg) {meth.apply(arg);}

上面的函數(shù)并沒(méi)有什么用,然而它至少可以提出一個(gè)想法:對(duì)函數(shù)作為第一個(gè)類成員的支持怎樣可以形成非常簡(jiǎn)潔且靈活的代碼:

applyArgument(Lambda::oneStringArgumentMethod, "X");

實(shí)現(xiàn)map

在諸多高階函數(shù)中,map是最經(jīng)典的. map的第一個(gè)參數(shù)是函數(shù),該函數(shù)可以接收一個(gè)參數(shù)并返回一個(gè)值;第二個(gè)參數(shù)是值列表. map使用傳入的函數(shù)處理值列表的每一項(xiàng),然后返回一個(gè)新的值列表。下面Python的代碼片段,可以很好的說(shuō)明map的用法:

>>> map(math.sqrt, [1, 4, 9, 16])[1.0, 2.0, 3.0, 4.0]

在本節(jié)的后續(xù)內(nèi)容中,將給出該函數(shù)的Java實(shí)現(xiàn)。Java 8已經(jīng)通過(guò)Stream提供了該函數(shù)。因?yàn)橹饕鲇诮虒W(xué)目的,所以,本節(jié)中給出的實(shí)現(xiàn)特意保持簡(jiǎn)單,僅限于List對(duì)象使用。

與Python不同,在Java中必須首先考慮map第一個(gè)參數(shù)的類型:一個(gè)可以接收一個(gè)參數(shù)并返回一個(gè)值的方法。參數(shù)的類型和返回值的類型可以不同。下面接口符合這個(gè)預(yù)期,顯然,I表示參數(shù)(入?yún)ⅲ?,O表示返回值(出參):

interface MapFunction {O apply(I in);}

泛型map方法的實(shí)現(xiàn),變得驚人的簡(jiǎn)單明了:

static List map(MapFunction func, List input) {List out = new ArrayList<>();for (I in : input) {out.add(func.apply(in));}return out;}

1.創(chuàng)建新的返回值列表out(用于保存O類型的對(duì)象).

2.通過(guò)遍歷input,func處理列表的每一項(xiàng),并將返回值添加到out中。

3.返回out.

下面是實(shí)際使用map方法的實(shí)例:

MapFunction func = Math::sqrt;List output = map(func, Arrays.asList(1., 4., 9., 16.));System.out.println(output);

在Python one-liner的推動(dòng)下,可以用更簡(jiǎn)潔的方法表達(dá):

System.out.println(map(Math::sqrt, Arrays.asList(1., 4., 9., 16.)));

Java畢竟不是Python...

Lambdas來(lái)了!

讀者可能會(huì)注意到,還沒(méi)有提到Lambdas。這是由于采用了“自下而上”的方式描述,現(xiàn)在基礎(chǔ)已基本建立,Lambdas將在后續(xù)的章節(jié)中介紹。

下面的用例作為基礎(chǔ):一個(gè)double類型的list,表示半徑,然后得到一個(gè)列表,表示圓面積。map方法就是為此任務(wù)預(yù)先準(zhǔn)備的。計(jì)算圓面積的公式是眾所周知的:

A?=?r2π

應(yīng)用這個(gè)公式的方法很容易實(shí)現(xiàn):

static Double circleArea(Double radius) {return Math.pow(radius, 2) * Math.PI;}

這個(gè)方法現(xiàn)在可以用作map方法的第一個(gè)參數(shù):

System.out.println(map(LambdaMap::circleArea,Arrays.asList(1., 4., 9., 16.)));

如果circleArea方法只需要這一次, 沒(méi)有道理把類接口被他弄得亂七八糟,也沒(méi)有道理將實(shí)現(xiàn)和真正使用它的地方分離。最佳實(shí)踐是使用用匿名內(nèi)部類??梢钥吹?,實(shí)例化一個(gè)實(shí)現(xiàn)MapFunction接口的匿名內(nèi)部類可以很好的完成這個(gè)任務(wù):

System.out.println(map(new MapFunction() {public Double apply(Double radius) {return Math.sqrt(radius) * Math.PI;}},Arrays.asList(1., 2., 3., 4.)));

這看起來(lái)很漂亮,但是很多人會(huì)認(rèn)為函數(shù)式的解決方案更清晰,更具可讀性:

List out = new ArrayList<>();for (Double radius : Arrays.asList(1., 2., 3., 4.)) {out.add(Math.sqrt(radius) * Math.PI);}System.out.println(out);

到目前為止,最后是使用Lambda表達(dá)式。 讀者應(yīng)該注意Lambda如何取代上面提到的匿名類:

System.out.println(map(radius -> { return Math.sqrt(radius) * Math.PI; },Arrays.asList(1., 2., 3., 4.)));

這看起來(lái)簡(jiǎn)潔明了 - 請(qǐng)注意 Lambda 表達(dá)式如何缺省任何明確的類型信息。 沒(méi)有顯式模板實(shí)例化,沒(méi)有方法簽名。

Lambda表達(dá)式由兩部分組成,這兩部分被->分隔。第一部分是參數(shù)列表,第二部分是實(shí)際實(shí)現(xiàn)。

Lambda表達(dá)式和匿名內(nèi)部類作用完全相同,然而它摒棄了許多編譯器可以自動(dòng)推斷的樣板代碼。讓我們?cè)俅伪容^這兩種方式,然后分析編譯器為開(kāi)發(fā)人員節(jié)省了哪些工作。

MapFunction functionLambda =radius -> Math.sqrt(radius) * Math.PI;MapFunction functionClass =new MapFunction() {public Double apply(Double radius) {return Math.sqrt(radius) * Math.PI;}};

對(duì)于Lambda實(shí)現(xiàn)來(lái)說(shuō),只有一個(gè)表達(dá)式,返回語(yǔ)句和花括號(hào)可以省略。這使得代碼更簡(jiǎn)短。  Lambda表達(dá)式的返回值類型是從Lambda實(shí)現(xiàn)推斷出來(lái)的。  對(duì)于參數(shù)類型,我不完全確定,但我認(rèn)為必須從Lambda表達(dá)式所處的上下文中推斷出參數(shù)類型。  最后編譯器必須檢查返回值類型是否與Lambda的上下文匹配,以及參數(shù)類型是否與Lambda實(shí)現(xiàn)匹配。

這一切都可以在編譯期間完成,根本沒(méi)有運(yùn)行時(shí)開(kāi)銷。

“怎么掌握J(rèn)ava中的Lambda”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


當(dāng)前文章:怎么掌握J(rèn)ava中的Lambda
轉(zhuǎn)載源于:http://weahome.cn/article/geidcs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部