Java stream多字段分组(groupingBy)实战

最近一个项目需求,后台录入市、区的经纬度信息,然后需要按照市、区来进行分组统计数量,去求如下:

部分表数据如下:

需求分析:按照市,区嵌套分组,区的分组好说,市的分组稍微麻烦一点,要先知道区的分组数量后,汇总求和。可以借助stream流的groupingBy分组函数轻松实现。

实体类:

public class MAssistFarmerInfo  {

    /**
     * 市code
     */
    private String cityCode;

    /**
     * 市名称
     */
    private String cityName;

    /**
     * 区code
     */
    private String countyCode;

    private String countyName;

    private String areaInfo;

    /**
     * 经度
     */
    private String longitude;

    /**
     * 纬度
     */
    private String latitude;

}

定义数据返回实体:

@Data
public class AreaInfoDto {

    /**
     * 地区code
     */
    private String code;
    /**
     * 地区名称
     */
    private String name;
    /**
     * 总计数
     */
    private Long total;
    /**
     * 子地区
     */
    private List<AreaInfoDto> children;
}

代码实现:

List<MAssistFarmerInfo> list = getAllData();
        List<AreaInfoDto> collect = list.stream()
                //按照市区嵌套分组
                .collect(Collectors.groupingBy(
                        MAssistFarmerInfo::getCityCode,
                        Collectors.groupingBy(MAssistFarmerInfo::getCountyCode, Collectors.counting())
                ))
                //转换,上一步分组后,得到的是Map<String,Map<String,Long>>,需要转换成List<AreaInfoDto>,
                //键是市的code,值是Map<String,Long>,即每个市下的区县code和数量
                .entrySet().stream().map(item -> {
                    AreaInfoDto earaInfo = new AreaInfoDto();
                    earaInfo.setCode(item.getKey());
                    List<AreaInfoDto> children = new ArrayList<>();
                    long count = 0;
                    for (Map.Entry<String, Long> stringLongEntry : item.getValue().entrySet()) {
                        AreaInfoDto childrenInfo = new AreaInfoDto();
                        childrenInfo.setCode(stringLongEntry.getKey());
                        childrenInfo.setTotal(stringLongEntry.getValue());
                        children.add(childrenInfo);
                        count += stringLongEntry.getValue();
                    }
                    earaInfo.setTotal(count);
                    earaInfo.setChildren(children);
                    return earaInfo;
                }).collect(Collectors.toList());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值