lambda 分类聚合_使用Java 8 Lambda,流和聚合
lambda 分類聚合
總覽
在本文中,我們將介紹使用Java 8 lambda,流和聚合來(lái)過(guò)濾和處理Collection中的對(duì)象。 這篇文章中的所有代碼都可以在此處的 BitBucket中找到 。
對(duì)于此示例,我們將創(chuàng)建許多對(duì)象,這些對(duì)象代表我們IT基礎(chǔ)架構(gòu)中的服務(wù)器。 我們將這些對(duì)象添加到列表中,然后使用lambda,流和聚合基于某些條件從列表中檢索服務(wù)器。
目標(biāo)
Lambdas
Lambda是Java的一項(xiàng)新功能,允許我們將功能或行為作為參數(shù)傳遞給方法。 一個(gè)說(shuō)明Lambda有用性的示例來(lái)自UI編碼。 當(dāng)用戶單擊用戶界面上的按鈕時(shí),通常會(huì)導(dǎo)致應(yīng)用程序中發(fā)生某些操作。 在這種情況下,我們確實(shí)希望將行為傳遞給onClick(…)方法,以便應(yīng)用程序?qū)⒃趩螕舭粹o時(shí)執(zhí)行給定的行為。 在Java的早期版本中,我們通過(guò)將匿名內(nèi)部類(實(shí)現(xiàn)了已知接口)傳遞給方法來(lái)實(shí)現(xiàn)此目的。 在這種情況下使用的接口通常僅包含一個(gè)方法,該方法定義了我們希望傳遞給onClick(…)方法的行為。 盡管這可行,但語(yǔ)法不方便。 匿名內(nèi)部類仍可用于此目的,但是新的Lambda語(yǔ)法更加簡(jiǎn)潔。
綜合運(yùn)營(yíng)
當(dāng)我們使用Collections將對(duì)象存儲(chǔ)在程序中時(shí),通常需要做的不僅僅是簡(jiǎn)單地將對(duì)象放入集合中-我們需要存儲(chǔ),檢索,刪除和更新這些對(duì)象。 聚合操作使用lambda對(duì)集合中的對(duì)象執(zhí)行操作。 例如,您可以使用聚合操作來(lái):
- 打印來(lái)自特定制造商的庫(kù)存中所有服務(wù)器的名稱
- 退還清單中早于特定期限的所有服務(wù)器
- 計(jì)算并返回清單中服務(wù)器的平均使用期限(前提是“服務(wù)器”對(duì)象具有“購(gòu)買日期”字段)
所有這些任務(wù)都可以通過(guò)使用聚合操作以及管道和流來(lái)完成。 我們將在下面看到這些操作的示例。
管道和流
流水線只是一系列聚合操作。 流是一個(gè)項(xiàng)目序列,而不是數(shù)據(jù)結(jié)構(gòu),它通過(guò)管道從源頭攜帶項(xiàng)目。 管道由以下部分組成:
一些聚合操作(例如forEach)看起來(lái)像迭代器,但是它們有根本的區(qū)別:
Lambda語(yǔ)法
既然我們已經(jīng)討論了與Lambda表達(dá)式有關(guān)的概念,現(xiàn)在該看看它們的語(yǔ)法了。 您可以將Lambda表達(dá)式視為匿名方法,因?yàn)樗鼈儧]有名稱。 Lambda語(yǔ)法包含以下內(nèi)容:
- 用括號(hào)分隔的形式參數(shù)的逗號(hào)分隔列表。 Lambda表達(dá)式中可以省略參數(shù)的數(shù)據(jù)類型。 如果只有一個(gè)形式參數(shù),則可以省略括號(hào)。
- 箭頭標(biāo)記:->
- 由單個(gè)表達(dá)式或代碼塊組成的主體。
使用Lambda,流和聚合操作
如概述中所述,我們將通過(guò)過(guò)濾和檢索List中的Server對(duì)象來(lái)演示lambda,流和聚合的用法。 我們來(lái)看四個(gè)例子:
讓我們開始吧…
服務(wù)器類
首先,我們來(lái)看一下Server類。 Server類將跟蹤以下內(nèi)容:
注意(在第65行),我們添加了getServerAge()方法,該方法根據(jù)購(gòu)買日期計(jì)算服務(wù)器的getServerAge()以年為單位)–在計(jì)算服務(wù)器中的平均壽命時(shí),將使用此方法庫(kù)存。
創(chuàng)建和加載服務(wù)器
現(xiàn)在我們有了Server類,我們將創(chuàng)建一個(gè)List并加載幾臺(tái)服務(wù)器:
示例1:打印所有Dell服務(wù)器的名稱
對(duì)于第一個(gè)示例,我們將編寫一些代碼來(lái)查找Dell制造的所有服務(wù)器,然后將服務(wù)器名稱打印到控制臺(tái):
我們的第一步是在第76行–我們必須從服務(wù)器列表中獲取流。 一旦有了流,就在第77行添加過(guò)濾器中間操作。過(guò)濾器操作將服務(wù)器流作為輸入,然后生成另一個(gè)服務(wù)器流,該服務(wù)器流僅包含與過(guò)濾器lambda中指定的條件匹配的服務(wù)器。 我們僅選擇Dell使用以下lambda制造的服務(wù)器: s -> s.getManufacturer().equalsIgnoreCase(manufacturer)
變量s表示從流中處理的每個(gè)服務(wù)器(請(qǐng)記住,我們不必聲明類型)。 箭頭運(yùn)算符的右側(cè)表示我們要為每個(gè)處理的服務(wù)器評(píng)估的語(yǔ)句。 在這種情況下,如果當(dāng)前服務(wù)器的制造商是Dell,我們將返回true,否則返回false。 過(guò)濾器產(chǎn)生的輸出流僅包含Dell制造的那些服務(wù)器。
最后,我們?cè)诘?8行上添加了forEach終端操作。forEach操作將服務(wù)器流作為輸入,然后在該流中的每個(gè)服務(wù)器上運(yùn)行給定的lambda。 我們使用以下lambda將Dell服務(wù)器的名稱打印到控制臺(tái): server -> System.out.println(server.getName())
請(qǐng)注意,我們?cè)诘谝粋€(gè)lambda中使用s作為流中每個(gè)服務(wù)器的變量名,在第二個(gè)lambda中使用server作為變量名-它們不必從一個(gè)lambda匹配到下一個(gè)lambda。
上面代碼的輸出是我們期望的:
示例2:打印所有超過(guò)三年的所有服務(wù)器的名稱
我們的第二個(gè)示例與第一個(gè)示例相似,不同之處在于我們要查找3年以上的服務(wù)器:
此示例與第一個(gè)示例之間的唯一區(qū)別是,我們將過(guò)濾器操作(第89行)中的lambda表達(dá)式更改為: s -> s.getServerAge() > age
該過(guò)濾器的輸出流僅包含3年以上的服務(wù)器。
上面代碼的輸出是:
示例3:將所有超過(guò)3年的服務(wù)器提取到新列表中
我們的第三個(gè)示例與第二個(gè)示例相似,因?yàn)槲覀冋趯ふ沂褂萌暌陨系姆?wù)器。 本示例中的不同之處在于,我們將創(chuàng)建一個(gè)僅包含滿足我們條件的服務(wù)器的新列表:
與前面的示例一樣,我們從列表中獲取流,并添加過(guò)濾器中間操作以創(chuàng)建僅包含3年以上服務(wù)器的流(第102和103行)。 現(xiàn)在,在第104行,我們使用collect終端操作而不是forEach終端操作。 collect終端操作將服務(wù)器流作為輸入,然后將它們放入?yún)?shù)中指定的數(shù)據(jù)結(jié)構(gòu)中。 在我們的例子中,我們將流轉(zhuǎn)換為服務(wù)器列表。 結(jié)果列表由第100行上聲明的oldServers變量引用。
最后,為了說(shuō)明在本示例中獲得的服務(wù)器與上一個(gè)服務(wù)器相同,我們?cè)趏ldServers列表中打印所有服務(wù)器的名稱。 請(qǐng)注意,因?yàn)槲覀兿M斜碇械乃蟹?wù)器,所以沒有中間過(guò)濾器操作。 我們只需從oldServers獲取流,并將其提供給forEach終端操作即可。
輸出是我們期望的:
示例4:計(jì)算并打印服務(wù)器的平均壽命
在最后一個(gè)示例中,我們將計(jì)算服務(wù)器的平均壽命:
第一步與前面的示例相同–我們從服務(wù)器列表中獲取流。 接下來(lái),我們添加mapToLong中間操作。 此聚合操作將服務(wù)器流作為輸入,并生成Longs流作為輸出。 根據(jù)第119行中指定的lambda將服務(wù)器映射到Longs(您也可以在第120行中使用等效語(yǔ)法)。 在這種情況下,我們要抓住每個(gè)傳入服務(wù)器的年齡,并將其放入生成的Longs流中。
接下來(lái),我們添加平均終端操作。 平均值完全符合您的期望-計(jì)算流中所有值的平均值。 諸如平均值之類的終端操作通過(guò)對(duì)流的內(nèi)容進(jìn)行合并或操作來(lái)返回一個(gè)值,這被稱為歸約操作 。 歸約運(yùn)算的其他示例包括sum , min , max和count 。
最后,我們添加操作getAsDouble 。 這是必需的,因?yàn)槠骄捣祷仡愋?strong>OptionalDouble 。 如果傳入流為空,則average將返回OptionalDouble的空實(shí)例。 如果發(fā)生這種情況,則調(diào)用getAsDouble將拋出NoSuchElementException ,否則它將僅在OptionalDouble實(shí)例中返回Double值。
該示例的輸出為:
結(jié)論
我們僅涉及到您可以使用lambda,流和聚合進(jìn)行處理的內(nèi)容。 我鼓勵(lì)您抓住源代碼,使用它,并開始探索這些Java 8新功能的所有可能性。
翻譯自: https://www.javacodegeeks.com/2015/12/using-java-8-lambdas-streams-aggregates.html
lambda 分類聚合
總結(jié)
以上是生活随笔為你收集整理的lambda 分类聚合_使用Java 8 Lambda,流和聚合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jwt令牌_JWT –生成和验证令牌–示
- 下一篇: 肯德基鸡块的做法 肯德基鸡块怎么做