【Java8】 Collectors工具類實現分組統計

分組、求和、求平均、求最大值、求最小值的統計在開發中經常會碰到。

之前在使用Mybatis的時候會直接用到聚合函數進行統計查詢。但是代碼中這樣寫會有一定的侷限性,比如:MySQL的聚合函數在程序切換數據庫 時聚合函數會失效。  亦或者是在微服務框架下,調用別人寫的接口時對方並未提供統計方法,所以分享一下通過Java8的Collectors類來實現分組的方式。其他聚合函數類似。

1、根據單字段分組,返回各類別總數。

Map<String,Long> consInfoGroupMap =
                consInfoVos.stream().collect(Collectors.groupingBy(ConsInfoVo::getSourceTypeName,Collectors.counting()));

Collectors.counting()表示直接分組返回count,其中,Map<String,Long>中的String即爲分組的字段,例如按照type分類,則這裏的string就是具體的某一個type類型,如:已處理,未處理等。後面的Long即爲每種類別的數量。需要組裝數據或者獲取數據時遍歷這個map即可。

 

2、根據單字段分組,返回各類的對象集合。

Map<Object, List<ConsInfoVo>> consInfoCollect =
                    consInfoVoList.stream().collect(
                            Collectors.groupingBy(ConsInfoVo -> ConsInfoVo.getStatus()));

執行該行代碼,返回值爲Map<String,List<ConsInfoVo>,很直觀的看出,返回的爲某一個分組的對象集合。同理,String爲分組的字段,List<> 爲分組後的對象集合。遍歷map即可操作集合。

 

3、根據單字段分組,返回類型爲對象。【分組字段爲時間,既按照時間按天分組】

Map<Object, List<ConsInfoVo>> consInfoCollect =
                    consInfoVoList.stream().collect(
                            Collectors.groupingBy(ConsInfoVo -> (ConsInfoVo.getCreateTime()).toLocalDate()));


//解析時注意類型轉換,因爲分組前將CreateTime轉換爲了LocalDate,
String groupDate = LocalDateUtil.localDateToStr((LocalDate) object);

數據庫creatTime字段爲LocalDateTime,所以分組前轉換爲LocalDate再去分組。

 

4、根據兩個字段分組,返回結果爲對象集合。

Map<String, Map<String, List<ConsMediaVo>>> consMediaCollect =
                    consMediaVoList.stream().collect(
                            Collectors.groupingBy(
                                    ConsMediaVo::getFileType, Collectors.groupingBy(ConsMediaVo -> ConsMediaVo.getStatus())));

以上代碼首先按照fileType分組,然後按照status分組。返回值Map<String, Map<String, List<OrderDealVo>>>,與上面的返回值雷同,無非是多了一層嵌套。最外層Map的key爲第一個分組字段的值,內部的Map的key爲第二個分組字段的值,之後便是解析list的過程。

分組後的結果集均爲Map,其中Map中的key的數據類型取決於分組字段的數據類型,當分組字段的類型改變,則Map的key的數據類型爲Object,轉換時爲改變後的數據類型,不然會報數據類型轉化異常。具體見如下例子:

 

5、根據兩個字段分組,返回結果爲對象集合。【其中一個分組字段爲時間,並且按天分組】

Map<String, Map<Object, List<ConsMediaVo>>> consMediaCollect =
                    consMediaVoList.stream().collect(
                            Collectors.groupingBy(
                                    ConsMediaVo::getFileType, Collectors.groupingBy(ConsMediaVo -> (ConsMediaVo.getCreateTime()).toLocalDate())));


//解析時注意類型轉換,因爲分組前將CreateTime轉換爲了LocalDate,
String groupDate = LocalDateUtil.localDateToStr((LocalDate) object);

以上代碼先按照fileType分類,然後按照創建時間分類。創建時間createTime在數據庫中存儲的是LocalDateTime類型,如果直接分組肯定是每天一條數據,所以需要將LocalDateTime轉換爲LocalDate去分組。這個時侯 數據類型變動了,所以 返回的爲Object類型的key值。其餘操作與之前類似。

可根據具體需求採取相應的方式,建議優先數據庫分組,因爲解析結果集是一個距大的工作量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章