Java中Stream流Map分組方式詳細(xì)匯總
前言
Stream是Java 8 API添加的一個新的抽象,稱為流Stream,以一種聲明性方式處理數(shù)據(jù)集合(側(cè)重對于源數(shù)據(jù)計算能力的封裝,并且支持序列與并行兩種操作方式)
Stream流是從支持?jǐn)?shù)據(jù)處理操作的源生成的元素序列,源可以是數(shù)組、文件、集合、函數(shù)。流不是集合元素,它不是數(shù)據(jù)結(jié)構(gòu)并不保存數(shù)據(jù),它的主要目的在于計算
Stream流是對集合(Collection)對象功能的增強,與Lambda表達(dá)式結(jié)合,可以提高編程效率、間接性和程序可讀性。
java老式的分組方式(對list for循環(huán)然后 if判斷 放入map) 代碼復(fù)雜,易讀性差,維護性差,故本文匯總了Stream流中的分組方法供大家參考
(以下方法默認(rèn)都是java8的方法,java9新增方法有標(biāo)注)
List<Student> studentList = Arrays.asList( new Student(1L,"小紅","籃球","紅色",22), new Student(2L,"小白","足球","藍(lán)色",11), new Student(3L,"小牛","足球","黑色",33), new Student(4L,"小羊","足球","紅色",17), new Student(5L,"小綠","足球","藍(lán)色",24));
1.常規(guī)按對象的字段直接將對象分組
按顏色分組
Map<String, List<Student>> byColor = studentList.stream() .collect(groupingBy(Student::getColor));
打印Map結(jié)果:
{紅色=[Student{id=1, name='小紅', hobby='籃球', color='紅色', age=22}, Student{id=4, name='小羊', hobby='足球', color='紅色', age=17}],
藍(lán)色=[Student{id=2, name='小白', hobby='足球', color='藍(lán)色', age=11}, Student{id=5, name='小綠', hobby='足球', color='藍(lán)色', age=24}],
黑色=[Student{id=3, name='小牛', hobby='籃球', color='黑色', age=33}]}
2.對分組的條件(key)做定義將對象進(jìn)行分組
按年紀(jì)是否大于十八歲分組
Map<String, List<Student>> collect1 = studentList.stream().collect(groupingBy(key -> { if (key.getAge() > 18) { return "成年"; } else { return "未成年"; } }));
打印Map結(jié)果:
{未成年=[Student{id=2, name='小白', hobby='足球', color='藍(lán)色', age=11}, Student{id=4, name='小羊', hobby='足球', color='紅色', age=17}],
成年=[Student{id=1, name='小紅', hobby='籃球', color='紅色', age=22}, Student{id=3, name='小牛', hobby='籃球', color='黑色', age=33}, Student{id=5, name='小綠', hobby='足球', color='藍(lán)色', age=24}]}
3.在分組時對數(shù)據(jù)進(jìn)行過濾
過濾掉不想要的數(shù)據(jù)時,在java8,需在分組前對集合進(jìn)行過濾,再分組。但會導(dǎo)致一類key中的元素都被過濾掉以后,分組結(jié)果不會有該key.
Map<String, List<Student>> collect = studentList.stream() .filter(f->!"紅色".equals(f.getColor())) .collect(groupingBy(Student::getColor));
打印Map結(jié)果:
{黑色=[Student{id=3, name='小牛', hobby='籃球', color='黑色', age=33}],
藍(lán)色=[Student{id=2, name='小白', hobby='足球', color='藍(lán)色', age=11}, Student{id=5, name='小綠', hobby='足球', color='藍(lán)色', age=24}]}
java9新增方法 filtering()方法,可以在分組時進(jìn)行過濾,以避免分組的結(jié)果map,因為過濾掉了一種key內(nèi)的所有元素導(dǎo)致map中沒有該key
filtering()
Map<String, List<Student>> collect = studentList.stream() .collect(groupingBy(Student::getColor, filtering(f->!"紅色".equals(f.getColor()),toList())));
打印Map結(jié)果:
{黑色=[Student{id=3, name='小牛', hobby='籃球', color='黑色', age=33}],
藍(lán)色=[Student{id=2, name='小白', hobby='足球', color='藍(lán)色', age=11}, Student{id=5, name='小綠', hobby='足球', color='藍(lán)色', age=24}],
紅色=[]}
4.在分組時,將收集的對象映射處理為其他值
Map<String, List<String >> collect = studentList.stream() .collect(groupingBy(Student::getColor,mapping(Student::getName,toList())));
打印Map結(jié)果:
{黑色=[小牛],
藍(lán)色=[小白, 小綠],
紅色=[小紅, 小羊]}
或?qū)apping()替換為其他方法對子組的數(shù)據(jù)進(jìn)行統(tǒng)計處理,比如maxBy()求子組中的Optional(最大值),或collectingAndThen(maxBy(),Optional::get)去除外層的Optional,直接獲得最大值.
或者替換為求和,sumInt等
5.在分組時,如果收集的value為list中包list,想將兩層list轉(zhuǎn)為一層,可使用flatmapping()方法
java9新增方法
和java8的flatmap()方法一樣,通過將需要收集的集合元素A收集到總集合B時,將A中的單個集合轉(zhuǎn)為Stream,和B的Stream通過flatmap()方法,將中間A的Stream去掉,當(dāng)A中的單個集合中的元素都拿出來放到B中.
兩層
Map<String,List<List<String>>> 將兩層List拆開 Map<String,List<String>>
Map<String, List<List<String >>> collect = studentList.stream() .collect(groupingBy(Student::getHobby, mapping(m->colorToMindMap.get(m.getColor()),toList()))); Map<String, List<String >> collect = studentList.stream() .collect(groupingBy(Student::getHobby, flatMapping(f->colorToMindMap.get(f.getColor()).stream(),toList())));
6.多級分組
所謂多級分組,就是在groupingBy(a,b)的第二個參數(shù)繼續(xù)放groupingBy(a,b)方法.規(guī)則和原來一樣.
在平時用的groupingBy(Student::getColor)內(nèi)部調(diào)用的其實就是groupingBy(Student::getColor,toList()), toList()方法就代表著將元素按list的形式來存儲到對應(yīng)的key下,改成groupBy(a,b)就是以分組的方式繼續(xù)存儲.
總結(jié)
到此這篇關(guān)于Java中Stream流Map分組方式的文章就介紹到這了,更多相關(guān)Java Stream流Map分組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java通過DelayQueue實現(xiàn)延時任務(wù)
本文主要介紹了java通過DelayQueue實現(xiàn)延時任務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07java文件操作報錯:java.io.FileNotFoundException(拒絕訪問)問題
在進(jìn)行編程時,經(jīng)常會遇到因疏忽小細(xì)節(jié)而導(dǎo)致的錯誤,如忘記在路徑后添加文件名,本文通過一個具體的修改前后對比示例,解釋了錯誤原因,并給出了解決方案,這類經(jīng)驗分享對編程學(xué)習(xí)者具有參考價值2024-10-10SpringBoot項目中訪問HTML頁面的實現(xiàn)示例
本文主要介紹了SpringBoot項目中訪問HTML頁面的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08解決Spring Cloud Feign 請求時附帶請求頭的問題
這篇文章主要介紹了解決Spring Cloud Feign 請求時附帶請求頭的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Mybatis中關(guān)于自定義mapper.xml時,參數(shù)傳遞的方式及寫法
這篇文章主要介紹了Mybatis中關(guān)于自定義mapper.xml時,參數(shù)傳遞的方式及寫法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Spring JDK動態(tài)代理實現(xiàn)過程詳解
這篇文章主要介紹了Spring JDK動態(tài)代理實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-02-02elasticsearch集群cluster?discovery可配式模塊示例分析
這篇文章主要為大家介紹了elasticsearch集群cluster?discovery可配式模塊示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04