聚合操作
你使用集合做什么?你不可能簡(jiǎn)單地將對(duì)象存儲(chǔ)在集合中并將它們留在那里,在大多數(shù)情況下,使用集合檢索存儲(chǔ)在其中的項(xiàng)。
再次考慮Lambda表達(dá)式小節(jié)中描述的場(chǎng)景,假設(shè)你正在創(chuàng)建一個(gè)社交網(wǎng)絡(luò)應(yīng)用程序,你希望創(chuàng)建一個(gè)功能,使管理員能夠?qū)M足某些條件的社交網(wǎng)絡(luò)應(yīng)用程序的成員執(zhí)行任何類型的操作,例如發(fā)送消息。
如前所述,假設(shè)這個(gè)社交網(wǎng)絡(luò)應(yīng)用程序的成員由以下Person類表示:
public class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress; // ... public int getAge() { // ... } public String getName() { // ... } }
下面的示例使用for-each循環(huán)打印集合roster中包含的所有成員的名稱:
for (Person p : roster) { System.out.println(p.getName()); }
下面的示例打印集合roster中包含的所有成員,但使用集合操作forEach:
roster .stream() .forEach(e -> System.out.println(e.getName());
盡管在本例中,使用聚合操作的版本比使用for-each循環(huán)的版本要長(zhǎng),但是你將看到,對(duì)于更復(fù)雜的任務(wù),使用批量數(shù)據(jù)操作的版本將更加簡(jiǎn)潔。
在示例BulkDataOperationsExamples中找到本節(jié)中描述的代碼摘錄。
管道和流管道是聚合操作的序列,下面的示例打印集合roster中包含的男性成員,其中包含由聚合操作filter和forEach組成的管道:
roster .stream() .filter(e -> e.getGender() == Person.Sex.MALE) .forEach(e -> System.out.println(e.getName()));
將此示例與下面的示例進(jìn)行比較,下面的示例打印集合roster中包含的男性成員,并使用for-each循環(huán):
for (Person p : roster) { if (p.getGender() == Person.Sex.MALE) { System.out.println(p.getName()); } }
管道包含以下組件:
源:可以是集合、數(shù)組、生成器函數(shù)或I/O通道,在本例中,源是集合roster。
零或多個(gè)中間操作,中間操作(如filter)生成一個(gè)新的流。
流是元素的序列,與集合不同,它不是存儲(chǔ)元素的數(shù)據(jù)結(jié)構(gòu),相反,流通過管道攜帶來自源的值,這個(gè)示例通過調(diào)用方法stream從集合roster創(chuàng)建一個(gè)流。
filter操作返回一個(gè)新的流,其中包含與其predicate匹配的元素(此操作的參數(shù)),在本例中,predicate是lambda表達(dá)式e -> e.getGender() == Person.Sex.MALE。如果對(duì)象e的gender字段的值為Person.Sex.MALE,則返回布爾值true,因此,本例中的filter操作返回一個(gè)包含集合roster中所有男性成員的流。
一個(gè)終端操作,終端操作(如forEach)生成非流結(jié)果,如原始值(如雙精度值)、集合,或者在forEach的情況下,根本沒有值。在本例中,forEach操作的參數(shù)是lambda表達(dá)式e -> System.out.println(e.getName()),調(diào)用對(duì)象e上的getName方法(Java運(yùn)行時(shí)和編譯器推斷對(duì)象e的類型是Person)。
下面的示例計(jì)算集合roster中包含的所有男性成員的平均年齡,其中管道由聚合操作filter、mapToInt和average組成:
double average = roster .stream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge) .average() .getAsDouble();
mapToInt操作返回一個(gè)類型為IntStream的新流(這是一個(gè)只包含整數(shù)值的流),該操作將其參數(shù)中指定的函數(shù)應(yīng)用于特定流中的每個(gè)元素,在這個(gè)例子中,函數(shù)是Person::getAge,它是一個(gè)方法引用,返回成員的年齡(或者,你可以使用lambda表達(dá)式e -> e. getage())。因此,本例中的mapToInt操作返回一個(gè)流,其中包含集合roster中所有男性成員的年齡。
average操作計(jì)算類型IntStream中包含的元素的平均值,它返回一個(gè)OptionalDouble類型的對(duì)象,如果流不包含元素,則average操作返回OptionalDouble的空實(shí)例,調(diào)用getAsDouble方法將拋出NoSuchElementException。JDK包含許多終端操作,比如average,通過組合流的內(nèi)容返回一個(gè)值,這些操作稱為歸納操作。
聚合操作和迭代器之間的區(qū)別像forEach這樣的聚合操作看起來像迭代器,然而,它們有幾個(gè)根本的區(qū)別:
它們使用內(nèi)部迭代:聚合操作不包含像next這樣的方法來指示它們處理集合的下一個(gè)元素,使用內(nèi)部委托,應(yīng)用程序決定迭代什么集合,但是JDK決定如何迭代集合,使用外部迭代,你的應(yīng)用程序?qū)⒋_定它迭代哪些集合以及如何迭代。然而,外部迭代只能按順序迭代集合的元素,內(nèi)部迭代沒有這種限制,它可以更容易地利用并行計(jì)算,這涉及到將一個(gè)問題劃分為子問題,同時(shí)解決這些問題,然后將子問題的解的結(jié)果組合起來。
它們處理來自流的元素:聚合操作處理流中的元素,而不是直接從集合中聚合,因此,它們也稱為流操作。
它們支持將行為作為參數(shù):可以將lambda表達(dá)式指定為大多數(shù)聚合操作的參數(shù),這使你能夠自定義特定聚合操作的行為。
上一篇:SortedMap接口文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75569.html
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實(shí)踐沒有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購(gòu)買。 入門 介紹Java技術(shù)和安裝Java開發(fā)軟件并使用...
Collection接口 Collection表示一組稱為其元素的對(duì)象,Collection接口用于傳遞需要最大通用性的對(duì)象集合,例如,按照慣例,所有通用集合實(shí)現(xiàn)都有一個(gè)帶有Collection參數(shù)的構(gòu)造函數(shù),此構(gòu)造函數(shù)(稱為轉(zhuǎn)換構(gòu)造函數(shù))初始化新集合以包含指定集合中的所有元素,無論給定集合的子接口或?qū)崿F(xiàn)類型如何,換句話說,它允許你轉(zhuǎn)換集合的類型。 例如,假設(shè)你有一個(gè)Collection c,它可...
Lambda表達(dá)式 匿名類的一個(gè)問題是,如果匿名類的實(shí)現(xiàn)非常簡(jiǎn)單,例如只包含一個(gè)方法的接口,那么匿名類的語法可能看起來不實(shí)用且不清楚,在這些情況下,你通常會(huì)嘗試將功能作為參數(shù)傳遞給另一個(gè)方法,例如當(dāng)有人單擊按鈕時(shí)應(yīng)采取的操作,Lambda表達(dá)式使你可以執(zhí)行此操作,將功能視為方法參數(shù),或?qū)⒋a視為數(shù)據(jù)。 上一節(jié)匿名類向你展示了如何在不給它命名的情況下實(shí)現(xiàn)基類,雖然這通常比命名類更簡(jiǎn)潔,但對(duì)于只有一個(gè)...
集合介紹 本節(jié)介紹Java集合框架,在這里,你將了解集合是什么以及它們?nèi)绾问鼓愕墓ぷ鞲p松、程序更好,你將了解構(gòu)成Java集合框架的核心元素 — 接口、實(shí)現(xiàn)、聚合操作和算法。 集合 — 有時(shí)稱為容器 — 只是一個(gè)將多個(gè)元素組合到一個(gè)單元中的對(duì)象,集合用于存儲(chǔ)、檢索、操作和傳遞聚合數(shù)據(jù)。通常,它們代表形成自然組的數(shù)據(jù)項(xiàng),例如撲克牌(卡片集合)、郵件文件夾(信件集合)或電話目錄(名稱到電話號(hào)碼的映射)...
摘要:接著我們將數(shù)據(jù)流按照單詞字段即號(hào)索引字段做分組,這里可以簡(jiǎn)單地使用方法,得到一個(gè)以單詞為的數(shù)據(jù)流。得到的結(jié)果數(shù)據(jù)流,將每秒輸出一次這秒內(nèi)每個(gè)單詞出現(xiàn)的次數(shù)。最后一件事就是將數(shù)據(jù)流打印到控制臺(tái),并開始執(zhí)行最后的調(diào)用是啟動(dòng)實(shí)際作業(yè)所必需的。 本文轉(zhuǎn)載自 Jark’s Blog ,作者伍翀(云邪),Apache Flink Committer,阿里巴巴高級(jí)開發(fā)工程師。 本文將從開發(fā)環(huán)境準(zhǔn)備、創(chuàng)建 ...
閱讀 2503·2021-11-24 10:29
閱讀 2644·2021-09-24 09:48
閱讀 5751·2021-09-22 15:56
閱讀 3163·2021-09-06 15:00
閱讀 2677·2019-08-30 15:54
閱讀 749·2019-08-30 13:48
閱讀 2927·2019-08-30 11:17
閱讀 3430·2019-08-29 11:20