摘要:上一篇我們介紹了的概念與實(shí)際的一些操作,本篇我們繼續(xù)來(lái)學(xué)習(xí)的另一個(gè)重要操作,分組與分區(qū)。注意到分組后的返回類型是,結(jié)果集中會(huì)將作為,對(duì)應(yīng)的集合作為返回。
上一篇我們介紹了Strem的概念與實(shí)際的一些操作,本篇我們繼續(xù)來(lái)學(xué)習(xí)Stream的另一個(gè)重要操作,分組與分區(qū)。
我們?cè)谏弦黄榻BStream的操作時(shí),會(huì)經(jīng)常使用到Collectors這個(gè)類,這個(gè)類實(shí)際上是一個(gè)封裝了很多常用的匯聚操作的一個(gè)工廠類。我們之前用到過(guò)
//將結(jié)果匯聚到ArrayList中 Collectors.toList();
//將結(jié)果匯聚到HashSet中 Collectors.toSet();
以及更為通用的
//將結(jié)果匯聚到一個(gè)指定類型的集合中 Collectors.toCollection(SuppliercollectionFactory);
Stream分組
在實(shí)際開發(fā)中,對(duì)于將一個(gè)集合的內(nèi)容進(jìn)行分組或分區(qū)這種需求也非常常見,所以我們繼續(xù)學(xué)習(xí)下Collectors類中的groupingBy和partitioningBy方法。
public static Collector groupingBy(Function super T, ? extends K> classifier){ //... }
groupingBy接收一個(gè)Function類型的變量classifier,classifier被稱作分類器,收集器會(huì)按著classifier作為key對(duì)集合元素進(jìn)行分組,然后返回Collector收集器對(duì)象,假如現(xiàn)在有一個(gè)實(shí)體Student
public class Student { private String name; private int score; private int age; public Student(String name,int score,int age){ this.name = name; this.score = score; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
我們現(xiàn)在按Student的name進(jìn)行分組,如果使用sql來(lái)表示就是select * from student group by name; 再看下使用Stream的方式
Map> collect = students.stream().collect(Collectors.groupingBy(Student::getName));
這里我們使用方法引用(類名::實(shí)例方法名)替代lambda表達(dá)式(s -> s.getName())的方式來(lái)指定classifier分類器,使集合按Student的name來(lái)分組。
注意到分組后的返回類型是Map
那如果按name分組后,想求出每組學(xué)生的數(shù)量,就需要借助groupingBy另一個(gè)重載的方法
public static Collector groupingBy(Function super T, ? extends K> classifier,Collector super T, A, D> downstream){ //... }
第二個(gè)參數(shù)downstream還是一個(gè)收集器Collector對(duì)象,也就是說(shuō)我們可以先將classifier作為key進(jìn)行分組,然后將分組后的結(jié)果交給downstream收集器再進(jìn)行處理
//按name分組 得出每組的學(xué)生數(shù)量 使用重載的groupingBy方法,第二個(gè)參數(shù)是分組后的操作 Mapcollect1 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
Collectors類這里也幫我們封裝好了用于統(tǒng)計(jì)數(shù)量的counting()方法,這里先了解一下counting()就是將收集器中元素求總數(shù)即可,后續(xù)我們會(huì)再深入源碼學(xué)習(xí)。
我們還可以對(duì)分組后的數(shù)據(jù)求平均值
Mapcollect2 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore)));
averagingDouble方法接收一個(gè)ToDoubleFunction參數(shù)
@FunctionalInterface public interface ToDoubleFunction{ /** * Applies this function to the given argument. * * @param value the function argument * @return the function result */ double applyAsDouble(T value); }
ToDoubleFunction實(shí)際上也是Function系列函數(shù)式接口中的其中一個(gè)特例,接收一個(gè)參數(shù),返回Double類型(這里是接收一個(gè)Student返回score)。因?yàn)榉纸M后的集合中每個(gè)元素是Student類型的,所以我們無(wú)法直接對(duì)Student進(jìn)行求平均值
//偽代碼 Collectors.averagingDouble(Student))
所以需要將Student轉(zhuǎn)成score再求平均值,Collectors.averagingDouble(Student::getScore))。
Stream分區(qū)
針對(duì)上面的Student,我們現(xiàn)在再加一個(gè)需求,分別統(tǒng)計(jì)一下及格和不及格的學(xué)生(分?jǐn)?shù)是否>=60)
這時(shí)候符合Stream分區(qū)的概念了,Stream分區(qū)會(huì)將集合中的元素按條件分成兩部分結(jié)果,key是Boolean類型,value是結(jié)果集,滿足條件的key是true,我們看下示例。
Map> collect3 = students.stream().collect(Collectors.partitioningBy(student -> student.getScore() >= 60)); System.out.println(collect3.get(true));//輸出及格的Student System.out.println(collect3.get(false));//輸出不及格的Student
partitioningBy方法接收一個(gè)Predicate作為分區(qū)判斷的依據(jù),滿足條件的元素放在key為true的集合中,反之放在key為false的集合中
//partitioningBy方法 public static Collector partitioningBy(Predicate super T> predicate) { return partitioningBy(predicate, toList()); }
下一篇
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/70778.html
摘要:這些切片稱為窗口。函數(shù)允許對(duì)常規(guī)數(shù)據(jù)流進(jìn)行分組。通常,這是非并行數(shù)據(jù)轉(zhuǎn)換,因?yàn)樗诜欠謪^(qū)數(shù)據(jù)流上運(yùn)行。 showImg(https://segmentfault.com/img/remote/1460000017874226?w=1920&h=1271); 前言 在第一篇介紹 Flink 的文章 《《從0到1學(xué)習(xí)Flink》—— Apache Flink 介紹》 中就說(shuō)過(guò) Flink ...
閱讀 1855·2021-11-25 09:43
閱讀 1498·2021-09-02 15:21
閱讀 3462·2019-08-30 15:52
閱讀 1507·2019-08-30 12:48
閱讀 1304·2019-08-30 10:57
閱讀 2934·2019-08-26 17:41
閱讀 684·2019-08-26 11:59
閱讀 1374·2019-08-26 10:41