使用Lambda表达式对List<Map<String,Object>>中key值相同的Map进行分组合并

现有两张表A表和B表,A表存放的是各省市的认证次数,B表存放的是各省市的申领次数,重点关注dq,cs这两个字段,其他的字段可忽略

                                                     A表(省市认证次数表)

                                                B表(省市申领次数表)

项目中有以下需求:

     现要求统计各省市的认证次数和申领次数,以及认证和申领次数之和,以此再地图上展示数据。

       A表和B表中都有dq和cs这两个字段,dq都表示行政区划编码,A表中的cs表示认证次数,B表中的cs表示申领次数,将两张表中dq值相同的分组放进同一个map中,再计算认证次数和申领次数之和,这个需求很明显就是Map要合并key的场景,将查出的数据进行合并,再分组,可使用Lambda表达式实现,部分代码如下:

Controller代码:

/**
     *  4、区域省份认证情况统计
     * @return
     */
@PostMapping(value="/loadProvinceAuthData")
    public ResponseVO loadProvinceAuthData() {
        try {
            Map<String, Object> data = new HashMap<>();
            ReportExternalRiskEntity request = new ReportExternalRiskEntity();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date=new Date();
            String startTime = sdf.format(date)+" 00:00:00";
            String endTime = sdf.format(date)+" 23:59:59";
            request.setStartTime(startTime);
            request.setEndTime(endTime);
            //List<Map<String,Object>> provinceAuthDataList = reportIdentityAuthStatService.getProvinceAuthDataList(request);
            List<Map<String,Object>> provinceAuthDataList = shenLingRenZhengService.getProvinceAuthDataList(request);
            data.put("list",provinceAuthDataList);
            return RespUtil.success(data);
        } catch (Exception e) {
            log.error("请求接口loadProvinceAuthData报错->{}",e);
            return RespUtil.sysError(String.valueOf(ResultCodeEnum.SYSTEM_ERROR));
        }
    }

 重点看Service代码中如何处理:

@Override
    public List<Map<String, Object>> getProvinceAuthDataList(ReportExternalRiskEntity request) throws Exception {
        List<Map<String, Object>> xzqhDataMapList = new ArrayList<>();

        Map queryParams = new HashMap();
        Date date=new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String queryDate = sdf.format(date);
        queryParams.put("ywrq",queryDate);
        List<Map<String, Object>> rzcsDqDataList = reportDpRzcsDqMapper.queryRzcsDqByYwrq(queryParams);//数据库查询认证次数返回的list
        List<Map<String, Object>> slcsDqDataList = reportDpSlcsDqMapper.querySlcsDqByYwrq(queryParams);//数据库查询申领次数返回的list

        PageData xzqhMap = CacheUtils.getTyZdMap(StaticVar.PROVICE_XZQH);
        if(CollectionUtils.isNotEmpty(rzcsDqDataList) && CollectionUtils.isEmpty(slcsDqDataList)){ //认证区域统计查询List有数据
            for (Map<String, Object> rzcsMap : rzcsDqDataList) {
                Map<String, Object> xzqhDataMap = new HashMap<>();
                //String authnumStr = (String) rzcsMap.get("authnum"); //注意:会报错java.math.BigDecimal cannot be cast to java.lang.Integer,先转成String类型,再转Integer
                //Integer authNum = (Integer) rzcsMap.get("authnum")==null?0:(Integer) rzcsMap.get("authnum");
                String authnumStr = StringUtils.isBlank(String.valueOf(rzcsMap.get("authnum")))?"0":String.valueOf(rzcsMap.get("authnum"));
                Integer authNum = Integer.parseInt(authnumStr);
                String rzdq = (String) rzcsMap.get("dq");
                String rzdq_bm = rzdq+StaticVar.XZQH_SUFFIX;
                xzqhDataMap.put("bm",rzdq_bm);
                xzqhDataMap.put("name",xzqhMap.get(rzdq_bm));
                xzqhDataMap.put("authNum",authNum);
                xzqhDataMap.put("applyNum",0);
                xzqhDataMap.put("totalNum",authNum);
                xzqhDataMap.put("leval",getLeval(authNum));
                xzqhDataMapList.add(xzqhDataMap);
            }
        }else if(CollectionUtils.isNotEmpty(slcsDqDataList) && CollectionUtils.isEmpty(rzcsDqDataList)){//申领区域统计查询List有数据
            for (Map<String, Object> slcsMap : slcsDqDataList) {
                Map<String, Object> xzqhDataMap = new HashMap<>();
                //Integer applyNum = (Integer) xzqhDataMap.get("applynum");
                String applynumStr = StringUtils.isBlank(String.valueOf(slcsMap.get("applynum")))?"0":String.valueOf(slcsMap.get("applynum"));
                Integer applyNum = Integer.parseInt(applynumStr);
                String sldq = (String) xzqhDataMap.get("dq");
                String sldq_bm = sldq+StaticVar.XZQH_SUFFIX;
                xzqhDataMap.put("bm",sldq_bm);
                xzqhDataMap.put("name",xzqhMap.get(sldq_bm));
                xzqhDataMap.put("authNum",0);
                xzqhDataMap.put("applyNum",applyNum);
                xzqhDataMap.put("totalNum",applyNum);
                xzqhDataMap.put("leval",getLeval(applyNum));
                xzqhDataMapList.add(xzqhDataMap);
            }
        }else if(CollectionUtils.isNotEmpty(rzcsDqDataList) && CollectionUtils.isNotEmpty(slcsDqDataList)) { //申领和认证都有数据

            for (Map<String, Object> rzcsMap : rzcsDqDataList) {
                String authnumStr = StringUtils.isBlank(String.valueOf(rzcsMap.get("authnum")))?"0":String.valueOf(rzcsMap.get("authnum"));
                Integer authNum = Integer.parseInt(authnumStr);
                rzcsMap.put("authNum",authNum);//将authnum替换为authNum
                rzcsMap.remove("authnum");//去掉那个authNum
            }

            for (Map<String, Object> slcsMap : slcsDqDataList) {
                String applynumStr = StringUtils.isBlank(String.valueOf(slcsMap.get("applynum")))?"0":String.valueOf(slcsMap.get("applynum"));
                Integer applyNum = Integer.parseInt(applynumStr);
                slcsMap.put("applyNum",applyNum);
                slcsMap.remove("applynum");
            }

            //合并,两个数据list放入一个新的list中
            List<Map<String, Object>> new_dataList = new ArrayList<>();
            new_dataList.addAll(rzcsDqDataList);
            new_dataList.addAll(slcsDqDataList);

            //先分组,将key值相同的放在一个map中
            xzqhDataMapList = new_dataList.stream()
                    .collect(Collectors.groupingBy(group -> group.get("dq").toString())) // 根据map中id的value值进行分组, 这一步的返回结果Map<String,List<Map<String, Object>>>
                    .entrySet() // 得到Set<Map.Entry<String, List<Map<String, Object>>>
                    .stream()
                    .map(m -> { // 进入映射环境
                        // m.getValue()的结果是 List<Map<String, Object>>
                        Map<String, Object> collect = m.getValue().stream()
                                // o.entrySet() 的结果是 Set<Map.Entry<String, Object>>
                                .flatMap(o -> o.entrySet().stream()).filter(e -> e.getValue() != null)//过滤下,value需要是不为空的,否则报错
                                // (m1, m2) -> m1 的意思是如果key相同 m1 == m2 则value使用m1(此处为rzcsDqDataList中的值)
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (m1, m2) -> m1
                                ));
                        return collect;
                    }).sorted(Comparator.comparing(m -> m.get("dq").toString())).collect(Collectors.toList());

            System.out.println("处理后的xzqhDataMapList为:"+xzqhDataMapList);
            System.out.println("处理后的xzqhDataMapList的Json为:"+ JSON.toJSONString(xzqhDataMapList));

            //处理分组后的数据,得到认证次数和申领次数之和totalNum
            for (Map<String, Object> xzqhDataMap : xzqhDataMapList) {
                String dq = (String) xzqhDataMap.get("dq");

                int totalNum = 0;
                Integer authNum = 0;
                Integer applyNum = 0 ;
                if(xzqhDataMap.containsKey("authNum")){
                    String authnumStr = StringUtils.isBlank(String.valueOf(xzqhDataMap.get("authNum")))?"0":String.valueOf(xzqhDataMap.get("authNum"));
                    authNum = Integer.parseInt(authnumStr);
                }

                if(xzqhDataMap.containsKey("applyNum")){
                    String applynumStr = StringUtils.isBlank(String.valueOf(xzqhDataMap.get("applyNum")))?"0":String.valueOf(xzqhDataMap.get("applyNum"));
                    applyNum = Integer.parseInt(applynumStr);
                }

                totalNum = authNum + applyNum;
                int level = getLeval(totalNum);
                xzqhDataMap.put("totalNum",totalNum);
                xzqhDataMap.put("level",level);
                if(!xzqhDataMap.containsKey("authNum")){ //若Map中没有"authNum",补key,"authNum"
                    xzqhDataMap.put("authNum",0);
                }

                if(!xzqhDataMap.containsKey("applyNum")){  若Map中没有"applyNum",补key,"applyNum"
                    xzqhDataMap.put("applyNum",0);
                }
                //行政区划翻译
                String xzqh_bm = dq+StaticVar.XZQH_SUFFIX;
                xzqhDataMap.put("bm",xzqh_bm);
                xzqhDataMap.put("name",xzqhMap.get(xzqh_bm));
                xzqhDataMap.remove("dq");
            }

        }
        
        return xzqhDataMapList;
    }

 //计算等级level值
  private static int getLeval(int totalNum) {
        int leval = 0;
        if(totalNum==0){
            return leval;
        }
        if(totalNum >=1 && totalNum <=900){
            leval = 1;
        }else if(totalNum >=901 && totalNum <=2000){
            leval = 2;
        }else if(totalNum >=2001 && totalNum <=4000){
            leval = 3;
        }else if(totalNum >=4001){
            leval = 4;
        }
        return leval;
    }
<!--查询认证次数返回的list-->
<select id="queryRzcsDqByYwrq" parameterType="java.util.Map" resultType="java.util.Map">
        select dq,sum(cs) as authNum from
            report_dp_rzcs_dq
        where ywrq =#{ywrq}
        group by dq
    </select>
  <!--查询申领次数返回的list-->
    <select id="querySlcsDqByYwrq" parameterType="java.util.Map" resultType="java.util.Map">
        select dq,sum(cs) as applyNum from
            report_dp_slcs_dq
        where ywrq = #{ywrq}
        group by dq
    </select>

请求接口http://127.0.0.1:8050/report/idauthstat/loadProvinceAuthData返回的数据结构如下:

{

    "data": {

        "list": [

            {

                "totalNum": 228,

                "level": 1,

                "authNum": 228,

                "name": "河北",

                "bm": "130000",

                "applyNum": 0

            },

            {

                "totalNum": 189,

                "level": 1,

                "authNum": 189,

                "name": "内蒙古",

                "bm": "150000",

                "applyNum": 0

            },

            {

                "totalNum": 356,

                "level": 1,

                "authNum": 356,

                "name": "辽宁",

                "bm": "210000",

                "applyNum": 0

            },

            {

                "totalNum": 798,

                "level": 1,

                "authNum": 662,

                "name": "吉林",

                "bm": "220000",

                "applyNum": 136

            },

            {

                "totalNum": 1260,

                "level": 2,

                "authNum": 1260,

                "name": "上海",

                "bm": "310000",

                "applyNum": 0

            },

            {

                "totalNum": 985,

                "level": 2,

                "authNum": 0,

                "name": "福建",

                "bm": "350000",

                "applyNum": 985

            },

            {

                "totalNum": 1006,

                "level": 2,

                "authNum": 0,

                "name": "江西",

                "bm": "360000",

                "applyNum": 1006

            },

            {

                "totalNum": 1209,

                "level": 2,

                "authNum": 0,

                "name": "山东",

                "bm": "370000",

                "applyNum": 1209

            },

            {

                "totalNum": 100,

                "level": 1,

                "authNum": 0,

                "name": "湖北",

                "bm": "420000",

                "applyNum": 100

            },

            {

                "totalNum": 1725,

                "level": 2,

                "authNum": 1725,

                "name": "湖南",

                "bm": "430000",

                "applyNum": 0

            },

            {

                "totalNum": 896,

                "level": 1,

                "authNum": 0,

                "name": "广东",

                "bm": "440000",

                "applyNum": 896

            },

            {

                "totalNum": 625,

                "level": 1,

                "authNum": 489,

                "name": "重庆",

                "bm": "500000",

                "applyNum": 136

            },

            {

                "totalNum": 789,

                "level": 1,

                "authNum": 0,

                "name": "四川",

                "bm": "510000",

                "applyNum": 789

            },

            {

                "totalNum": 623,

                "level": 1,

                "authNum": 623,

                "name": "陕西",

                "bm": "610000",

                "applyNum": 0

            },

            {

                "totalNum": 1024,

                "level": 2,

                "authNum": 0,

                "name": "新疆",

                "bm": "650000",

                "applyNum": 1024

            },

            {

                "totalNum": 420,

                "level": 1,

                "authNum": 420,

                "name": "台湾",

                "bm": "710000",

                "applyNum": 0

            },

            {

                "totalNum": 876,

                "level": 1,

                "authNum": 876,

                "name": "香港",

                "bm": "810000",

                "applyNum": 0

            }

        ]

    },

    "msg": "操作成功",

    "success": true,

    "code": "I000000",

    "total": null

}

统计完成,可参考 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/37125.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

qt完整教程

各个组件的意思(功能介绍) Python Qt GUI设计:UI界面可视化组件、属性概述(基础篇—3)-腾讯云开发者社区-腾讯云 qt 如何设计好布局和漂亮的界面。_qt界面_花狗Fdog的博客-CSDN博客 样式表(美化关键)/*灰色*/ Q/*灰色*/ QWidget {background-color: rgb(255, 182, …

MySQL-概述-数据模型SQL简介

数据库&#xff1a;DataBase&#xff08;DB&#xff09;&#xff0c;是存储和管理数据的仓库数据库管理系统&#xff1a;DataBase Management System&#xff08;DBMS&#xff09;&#xff0c;操作和管理数据库的大型软件。SQL&#xff1a;Structured Query Language&#xff0…

汇报方案设计方案规划方案资源下载

标题汇报方案设计方案规划方案资源下载https://wheart.cn/so/home?mdw&tag%E5%AE%89%E5%85%A8文章标签事业单位人事人才信息综合管理系统建设设计报价方案人事系统,人事人才,事业单位,工资系统,职称系统xx纪检委智慧监督平台建设方案汇报.docx建设方案,规划设计,汇报方案营…

【C++】priority_queue使用与模拟实现

认识priority_queue 1、priority_queue(优先级队列)是一种容器适配器&#xff0c;底层是一个完全二叉树的大堆&#xff08;堆总是一颗完全二叉树&#xff0c;根结点最大的堆叫做大堆&#xff1b;根结点最小的堆叫做小堆&#xff09;&#xff0c;头文件在queue中&#xff0c;根…

入侵排查与响应-window和linux版

目录 &#xff08;一&#xff09;关于这方面的一些简单了解 1、我们的电脑为什么会被黑客入侵 2、黑客攻击的方式 &#xff08;二&#xff09;window入侵排查 1、查看异常特征 2、系统账户安全 3、检测异常端口、进程 4、查看启动项、计划任务、服务 5、检查系统相关信…

Spring Cloud微服务治理框架深度解析

在学习一个技术之前&#xff0c;首先我们要了解它是做什么的&#xff0c;我们为什么要用它。不然看再多资料都理解不了&#xff0c;因此我们先来讲解下Spring Cloud Spring Cloud是一套微服务治理框架&#xff0c;几乎考虑到了微服务治理的方方面面。那么接下来具体说下 Spring…

Linux 的常用命令

文章目录 lsllcdpwd编辑简单文件touchcatecho 编辑复杂文件vim mkdirrmcpmvgerppsnetstat总结 ls 查看当前目录或指定目录下的所有文件 ls 什么都不加表示查看当前目录中的内容 ls目录名&#xff0c;就是插卡指定目录下的所有文件。/代表根目录。 注&#xff1a;蓝色的表示目…

【Leetcode】42.接雨水(困难)

一、题目 1、题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6…

OpenCV实现一张图片的特定区域上添加另一张图片

#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace cv;int main( ){Mat image= imread

java并发编程 10:AQS

目录 什么是AQS原理 什么是AQS juc包的结构如下图&#xff1a; AQS就是AbstractQueuedSynchronizer&#xff0c;是个抽象类&#xff0c;实现了自己的一些方法。它是阻塞式锁和相关的同步器工具的框架。很多并发类都是基于它实现的&#xff0c;如&#xff1a;ReentrantLock、Co…

Edge浏览器无法展示Stable Diffusion Control Net插件

Edge浏览器无法展示Stable Diffusion Control Net插件 最近在学习Stable Diffusion&#xff0c;需要使用到Control Net插件&#xff0c;结果通过各种方式安装成功插件后&#xff0c;浏览器页面没有展示ControlNet相关页面&#xff0c;最终换到Chorme浏览器后正常&#xff0c;猜…

连接区块链节点的 JavaScript 库 web3.js

文章目录 前言web3.js 介绍web3.js安装web3.js库模块介绍连接区块链节点向区块链网络发送数据查询区块链网络数据 前言 通过前面的文章我们可以知道基于区块链开发一个DApp&#xff0c;而DApp结合了智能合约和用户界面&#xff08;客户端&#xff09;&#xff0c;那客户端是如…

设计模式——工厂方法模式

工厂方法模式 定义 工厂方法模式的使用频率非常高 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法将一个类的实例化延迟到其子类。 优缺点、使用场景 优点 良好的封装性&#xff0c;代码结构清晰。调用者需要一个产品&#xff0c;只需要知道…

图书馆工作效率太低?请疯狂使用这个工具!

在当今社会&#xff0c;对于公共场所的安全和保护变得越来越重要。图书馆作为一个重要的知识资源中心和学习场所&#xff0c;同样需要采取措施来确保其内部环境的安全性。其中&#xff0c;烟雾监控是一项关键的安全措施。 客户案例 浙江某图书馆每天都有大量的读者访问&#xf…

35.RocketMQ之Broker端消息存储文件详解

highlight: arduino-light Broker端文件详解 dubbo的核心是spi&#xff0c;看懂了spi那么dubbo基本上也懂了。对于rmq来说&#xff0c;它的核心是broker&#xff0c;而broker的核心是commitlog、consumequeue、indexfile&#xff0c;而这些文件对应的最终都是MappedFile&#x…

3.1 Bootstrap 字体图标(Glyphicons)

文章目录 Bootstrap 字体图标(Glyphicons)什么是字体图标&#xff1f;获取字体图标CSS 规则解释带有导航栏的字体图标定制字体图标定制字体尺寸定制字体颜色应用文本阴影 Bootstrap 字体图标(Glyphicons) 本章将讲解字体图标(Glyphicons)&#xff0c;并通过一些实例了解它的使用…

2023-07-11力扣每日一题

链接&#xff1a; https://leetcode.cn/problems/maximum-alternating-subsequence-sum/ 题意&#xff1a; 给定一个数组&#xff0c;求一个子序列&#xff0c;使这个子序列的奇数位和-偶数位和最大&#xff08;下标从1开始的话|反正第一个数是&#xff09; 解&#xff1a;…

【STM32MP135】修复10.1寸屏显示异色问题,添加极性配置

文件路径&#xff1a;u-boot-stm32mp-v2021.10-stm32mp1-r1/drivers/video/stm32/stm32_ltdc.c

Microsoft 宣布今年底关闭开源软件托管平台 CodePlex

Microsoft 宣布&#xff0c;将关闭开源软件托管平台 CodePlex。Microsoft 2006 年推出这项服务&#xff0c;并决定在今年 12 月 15 日将其关闭。 Microsoft 公司副总裁 Brian Harry 在网上博客中写道&#xff0c;人们将可以下载他们的数据档案&#xff0c;Microsoft 正与面向开…

使用C语言连接MySQL

目录 一、引入库 1.1 下载库文件 1.2 在项目中引入库 二、使用库 2.1 连接数据库 2.2 SQL请求 2.3 获取查询结果 2.4 使用案例 一、引入库 1.1 下载库文件 要使用C语言连接MySQL&#xff0c;需使用MySQL官网提供的库 MySQL :: Download Connector/Chttps://dev.mysq…