一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - Java函數(shù)式編程(三):列表的轉(zhuǎn)化

Java函數(shù)式編程(三):列表的轉(zhuǎn)化

2019-11-29 16:18deepinmind JAVA教程

這篇文章主要介紹了Java函數(shù)式編程(二):列表的轉(zhuǎn)化,lambda表達(dá)式不僅能幫助我們遍歷集合,并且可以進(jìn)行集合的轉(zhuǎn)化,需要的朋友可以參考下

列表的轉(zhuǎn)化

將集合轉(zhuǎn)化成一個(gè)新的集合就和遍歷它一樣簡(jiǎn)單。假設(shè)我們要將列表中的名字轉(zhuǎn)化成全大寫的。我們看下都有哪些實(shí)現(xiàn)方式。

Java中的字符串是不可變的,所以它沒(méi)法改變。我們可以生成新的字符串,用來(lái)替換列表中原有的元素。然而這樣做的話,原來(lái)列表就沒(méi)了;還有一個(gè)問(wèn)題,原來(lái)的列表可能也是不可變的,比如Arrays.asList()生成的,所以修改原來(lái)的列表這招不行。還有一個(gè)缺點(diǎn)就是這樣做很難并行操作。

生成一個(gè)新的全大寫的列表是個(gè)不錯(cuò)的選擇。

乍聽(tīng)起來(lái)這個(gè)建議弱爆了;性能是我們都很關(guān)注的一個(gè)問(wèn)題。令人吃驚的是,函數(shù)式編程通常要比命令式的性能要高,我們?cè)?53頁(yè)的性能問(wèn)題中會(huì)講到。

我們先開(kāi)始用這個(gè)集合生成一個(gè)大寫字母的新集合吧。

復(fù)制代碼代碼如下:

final List<String> uppercaseNames = new ArrayList<String>();
for(String name : friends) {
uppercaseNames.add(name.toUpperCase());
}


在命令式的代碼中,我們先創(chuàng)建一個(gè)空列表,然后把大寫的名字填充進(jìn)去,在遍歷原來(lái)列表的過(guò)程中,每次插入一個(gè)。為了改進(jìn)成函數(shù)式的版本,我們第一步可以考慮采用19頁(yè)遍歷列表中提到的那個(gè)內(nèi)部迭代器forEach來(lái)替換一下for循環(huán),正如下例所示的那樣。

復(fù)制代碼代碼如下:

final List<String> uppercaseNames = new ArrayList<String>();
friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
System.out.println(uppercaseNames);


我們用了內(nèi)部迭代器,但還得新建一個(gè)列表,然后再把元素插入到里面。我們還可以進(jìn)一步改進(jìn)。

 

使用lambda表達(dá)式

一個(gè)新引入的Stream接口里面,有個(gè)map方法,它可以幫助我們遠(yuǎn)離可變性,并使代碼看起來(lái)更簡(jiǎn)潔。Steam有點(diǎn)像集合的迭代器,同時(shí)它還提供了流函數(shù)(fluent functions)的功能。使用這個(gè)接口的方法,我們可以把一系列調(diào)用給組合起來(lái),使代碼讀起來(lái)就像描述問(wèn)題的順序一樣,可讀性更強(qiáng)。

Steam的map方法可以用來(lái)將輸入序列轉(zhuǎn)化成一個(gè)輸出的序列——這和我們要做的工作非常匹配。

 

復(fù)制代碼代碼如下:

friends.stream()
.map(name -> name.toUpperCase())
.forEach(name -> System.out.print(name + " "));
System.out.println();

 

JDK8中的所有集合都支持這個(gè)stream方法,它把集合封裝成一個(gè)Steam實(shí)例。map方法對(duì)Stream中的每個(gè)元素都調(diào)用了指定的lambda表達(dá)式或者代碼塊。map方法跟forEach方法很不一樣, forEach只是簡(jiǎn)單的對(duì)集合中的元素執(zhí)行了一下指定的函數(shù)。而map方法把lambda表達(dá)式的運(yùn)行結(jié)果收齊起來(lái),返回一個(gè)結(jié)果集。最后我們用forEach方法打印了所有的元素。

新集合中的名字全都是大寫的了:

復(fù)制代碼代碼如下:

BRIAN NATE NEAL RAJU SARA SCOTT

 

map方法很適合把一個(gè)輸入集合轉(zhuǎn)化成一個(gè)新的輸出集合。這個(gè)方法確保了輸入輸出序列的元素的數(shù)量是相同的。然而輸入元素和輸出元素的類型可以是不一樣的。在這個(gè)例子中,我們輸入和輸出的都是字符串的集合。我們可以傳給map方法一段代碼,讓它返回比如說(shuō)名字中包含字符的個(gè)數(shù)。這樣的話,輸入的還是字符串的序列,而輸出的卻是數(shù)字序列了,就像下面這樣。

復(fù)制代碼代碼如下:

friends.stream()
.map(name -> name.length())
.forEach(count -> System.out.print(count + " "));


結(jié)果是每個(gè)名字中字母的個(gè)數(shù):

復(fù)制代碼代碼如下:

5 4 4 4 4 5

 

使用了lambda表達(dá)式的之后版本,避免了顯式的修改操作;這樣的代碼非常簡(jiǎn)潔。這樣寫不再需要初始化空的集合以及那個(gè)垃圾變量了;這個(gè)變量乖乖的躲到了底層實(shí)現(xiàn)里面了。

使用方法引用

我們還可以使用方法引用讓它變得更簡(jiǎn)潔一些。在需要傳入函數(shù)式接口的實(shí)現(xiàn)的地方,Java編譯器可以接受lambda表達(dá)式或者是方法引用。有了這個(gè)特性,用String::toUpperCase就可以替換掉name -> name.toUpperCase()了,就像這樣:

復(fù)制代碼代碼如下:

friends.stream()
.map(String::toUpperCase)
.forEach(name -> System.out.println(name));

 

當(dāng)參數(shù)傳入到這個(gè)生成的方法——函數(shù)式接口的抽象方法的實(shí)現(xiàn)——里面的時(shí)候,Java會(huì)去調(diào)用這個(gè)String參數(shù)的toUpperCase方法。這個(gè)參數(shù)引用在這里就隱藏起來(lái)了。像前面這種簡(jiǎn)單的場(chǎng)景,我們可以用方法引用來(lái)替換掉lambda表達(dá)式;更多的內(nèi)容看一下26頁(yè)的什么時(shí)候應(yīng)該使用方法引用。

復(fù)制代碼代碼如下:


小伙伴發(fā)問(wèn)了: 
什么時(shí)候應(yīng)該使用方法引用?

 

當(dāng)使用Java編程的時(shí)候,通常我們用lambda表達(dá)式的時(shí)候要比方法引用多得多。但這并不意味著方法引用不重要或者沒(méi)啥用處。當(dāng)lambda表達(dá)式非常簡(jiǎn)短的時(shí)候,它是一個(gè)很好的替代方案,它直接調(diào)用了實(shí)例方法或者靜態(tài)方法。也就是說(shuō),如果lambda表達(dá)式只是傳遞了一下參數(shù)給方法調(diào)用的話,我們應(yīng)該改用方法引用。 
像這樣的lambda表達(dá)式,有點(diǎn)像Tom Smykowski在電影上班一條蟲(chóng)中講的那樣,它的工作就是"從客戶那把需求拿給軟件工程師"。因?yàn)檫@個(gè),我把這種重構(gòu)成方法引用的模式叫做上班一條蟲(chóng)模式。 
除了簡(jiǎn)潔外,使用方法引用,方法名字本身的含義和作用可以更好的體現(xiàn)出來(lái)。 
使用方法引用背后,編譯器起到了很關(guān)鍵的作用。方法引用的目標(biāo)對(duì)象和參數(shù)都會(huì)從這個(gè)生成的方法里傳進(jìn)來(lái)的參數(shù)那推導(dǎo)出來(lái)。這才使得你可以使用方法引用寫出比使用lambda表達(dá)式更簡(jiǎn)潔的代碼。不過(guò),如果參數(shù)在傳遞給方法之前或者調(diào)用結(jié)果在返回之后要被修改的話,這種便利的寫法我們就用不了了。

 

在前面這個(gè)例子中,方法引用是引用了一個(gè)實(shí)例方法。方法引用還可以引用一個(gè)靜態(tài)方法以及接受傳參的方法。后面我們會(huì)看到這樣的例子。

lambda表達(dá)式能幫助我們遍歷集合,并且進(jìn)行集合的轉(zhuǎn)化。就像下面我們即將看到的,它還能幫助我們快速的從集合中選取一個(gè)元素。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 大胸孕妇孕交pregnantsex 大象视频污 | 国产黑丝一区 | 亚洲国产精品无码中文在线 | 色就色欧美综合偷拍区a | 欧美精品色精品一区二区三区 | 香蕉久久高清国产精品免费 | 视频一区二区三区在线观看 | 红楼影视h38bar在线线播放 | 美女黄金大片视频免费看 | 欧美特黄一级大片 | 美女被吸乳得到大胸 | 香蕉免费看一区二区三区 | 52zfl宅福利yxpjw | 免费黄色小说 | 日本视频高清免费观看xxx | 91香蕉国产在线观看人员 | 免费一级欧美片片线观看 | 91这里只有精品 | 91婷婷射| 扒开放荡老师裙子猛烈的进入 | 肉色欧美久久久久久久蜜桃 | 精品视频 九九九 | 国产ay | 青青草伊人久久 | se01在线看片 | 性色AV一区二区三区V视界影院 | 日韩夫妻性生活 | a毛片久久免费观看 | 国内精品一区二区三区东京 | 国产在线一区二区视频 | 四虎国产成人亚洲精品 | 国产高清在线精品一区 | 91精品国产高清久久久久久io | 国产suv精品一区二区四区三区 | 国产精品网站在线观看 | 免费大片a一级一级 | 成人免费草草视频 | 国产不卡视频 | 91在线精品视频 | 日本精品人妖shemale人妖 | 男人摸女人下面 |