日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

用流收集数据Collectors的用法介绍分组groupingBy、分区partitioningBy(一)

發(fā)布時(shí)間:2025/1/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用流收集数据Collectors的用法介绍分组groupingBy、分区partitioningBy(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 一、收集器簡(jiǎn)介
    • 二、歸約和匯總
      • 1、查找流中最大值和最小值Collectors.maxBy和,Collectors.minBy
      • 2、匯總
      • 3、連接字符串
      • 4、廣義歸約匯總
    • 三、分組
      • 1、多級(jí)分組
      • 2、按子組收集數(shù)據(jù)
      • 3、將收集器結(jié)果轉(zhuǎn)換為另一種類(lèi)型
      • 4、分區(qū)partitioningBy

這一張我們主要講用流來(lái)收集數(shù)據(jù),函數(shù)式的編程相對(duì)于指令式編程的一個(gè)優(yōu)勢(shì):你只需指出希望的結(jié)果做什么,而不用操心執(zhí)行的步驟怎么做。

這一節(jié)所講的方法都是基于收集collect里面參數(shù)Collectors里面的靜態(tài)方法靜態(tài)方法。

小插曲:import static java.util.stream.Collectors.*;可以把所有靜態(tài)方法引入

一、收集器簡(jiǎn)介

收集器非常有用,因?yàn)樗梢院?jiǎn)潔而又靈活地定義collect用來(lái)生成結(jié)果集合的標(biāo)準(zhǔn)。更具體說(shuō),對(duì)流調(diào)用collect方法將對(duì)流中的元素發(fā)一個(gè)歸約操作。
本章剩下部分,主要探討預(yù)定義收集器功能,也就是那些可以從Collector類(lèi)提供的工廠(chǎng)方法創(chuàng)建收集器。主要提供三大功能:

  • 將流元素歸約和匯總一個(gè)值
  • 元素分組
  • 元素分區(qū)

二、歸約和匯總

利用counting

public static void testCounting() {Long collect = menu.stream().collect(counting());}

1、查找流中最大值和最小值Collectors.maxBy和,Collectors.minBy

maxBy參數(shù)接受一個(gè)Compartor比較結(jié)果。例:

public static void testMaxby() {Comparator<Dish> dishComparator = Comparator.comparingInt(Dish::getCalories);Optional<Dish> collect = menu.stream().collect(maxBy(dishComparator));}

2、匯總

Collectors類(lèi)專(zhuān)門(mén)為匯總提供了一個(gè)工廠(chǎng)方法:Collectors.summingInt。接受一個(gè)對(duì)象映射為求和所需int函數(shù)。例:

public static void testSummingInt() {Integer collect = menu.stream().collect(summingInt(Dish::getCalories));System.out.println(collect);}

Collectors.summingLong和Collectors.summingDouble方法用法完全一樣可以用于求和long和double,求平球輸方法averagingLong、averagingDouble、averagingInt。
summarizingInt、summarizingLong、summarizingDouble方法可以數(shù)出元素個(gè)數(shù)、平均數(shù)、總和、最大值和最小值。例:

IntSummaryStatistics menuStatistics = menu.stream().collect(summarizingInt(Dish::getCalories));

3、連接字符串

joining工廠(chǎng)方法返回的收集器會(huì)把中每一個(gè)對(duì)象應(yīng)用toString()方法得到的所有字符串
連接成一個(gè)字符串。例:把所有的菜肴名稱(chēng)連接起來(lái)

public static void testJoining() {String collect = menu.stream().map(Dish::getName).collect(joining());System.out.println(collect);}

重載方法可以添加用什么分隔符

public static void testJoining() {String collect = menu.stream().map(Dish::getName).collect(joining(","));System.out.println(collect);}

4、廣義歸約匯總

前面已經(jīng)討論過(guò)的收集器,可以用一個(gè)reduing工廠(chǎng)方法定義歸約過(guò)程的特殊情況。例:

public static void testCollectReduing() {Integer collect = menu.stream().collect(reducing(0, Dish::getCalories, (i, j) -> i + j));}

它需要三個(gè)參數(shù):
第一個(gè)參數(shù):歸約起始位置
第二個(gè)參數(shù):轉(zhuǎn)換成表示所函熱量的int
第三個(gè)參數(shù):是一個(gè)BInaryOperator,將兩個(gè)項(xiàng)目累計(jì)為同一個(gè)值。例如對(duì)int求和。

三、分組

java8分組類(lèi)似于常見(jiàn)數(shù)據(jù)庫(kù)分組,我們java8提供了Collectors.groupingBy工廠(chǎng)方法返回的收集器就可以輕松的完成分組。例:
按照菜單類(lèi)型分組

Map<Dish.Type, List<Dish>> dishesByType = menu.stream().collect(groupingBy(Dish::getType));

1、多級(jí)分組

實(shí)現(xiàn)多級(jí)分組,可以使用一個(gè)由雙參數(shù)版本的Collectors.groupingBy工廠(chǎng)方法創(chuàng)建收集器,除了普通的分類(lèi)函數(shù)外,還可以接受collector類(lèi)型的第二個(gè)參數(shù)。進(jìn)行二級(jí)分組可以把內(nèi)層的groupingby傳遞給外層。
例:

public static void testCollecGroupBying() {Map<Type, Map<CaloricLevel, List<Dish>>> collect = menu.stream().collect(groupingBy(Dish::getType, groupingBy(dish ->{if (dish.getCalories() <= 400) return CaloricLevel.DIET;else if (dish.getCalories() <= 700) return CaloricLevel.NOMAL;else return CaloricLevel.FAT;})));System.out.println(collect);}

n級(jí)分組就會(huì)得到一個(gè)n級(jí)樹(shù)形結(jié)構(gòu)的n級(jí)Map

2、按子組收集數(shù)據(jù)

傳遞給第一個(gè)groupingBy的第二個(gè)收集器可以是任何類(lèi)型,而不一定是一個(gè)groupingBy。例:

Map<Dish.Type, Long> typesCount = menu.stream().collect( groupingBy(Dish::getType, counting()));

注意:普通單參數(shù)groupingBy單參數(shù)其實(shí)就是groupbingBy(f,toList)的簡(jiǎn)寫(xiě)

在舉一個(gè)例子加深印象

Map<Type, Optional<Dish>> collect1 = menu.stream().collect(groupingBy(Dish::getType,maxBy(Comparator.comparingInt(Dish::getCalories))));

3、將收集器結(jié)果轉(zhuǎn)換為另一種類(lèi)型

收集器轉(zhuǎn)換成另一種類(lèi)型可以用:Collectors.collectingAndThen
例:

public static void testCollectAndThen() {Map<Type, Dish> collect = menu.stream().collect(groupingBy(Dish::getType,collectingAndThen(maxBy(Comparator.comparingInt(Dish::getCalories)), Optional::get)));} }

collectingAndThen工廠(chǎng)發(fā)方法接受兩個(gè)參數(shù):1、轉(zhuǎn)換收集器(Collector);2、轉(zhuǎn)換函數(shù)(Function)。返回值是另一個(gè)收集器。

4、分區(qū)partitioningBy

分區(qū)的好處在于保留分區(qū)函數(shù)返回true或false的兩套流元素列表。partitioningBy工廠(chǎng)方法有一個(gè)重載方法,第二個(gè)參數(shù)可以傳遞收集器。

public static void testPartitioningBy() {Map<Boolean, Map<Type, List<Dish>>> collect = menu.stream().collect(partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType)));}

總結(jié):Collectors類(lèi)的靜態(tài)工廠(chǎng)方法



總結(jié)

以上是生活随笔為你收集整理的用流收集数据Collectors的用法介绍分组groupingBy、分区partitioningBy(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。