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

news2024/11/16 10:35:42

现有两张表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

}

统计完成,可参考 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

辅助性能优化——长安链性能分析工具原理及用法

如何提升区块链系统性能是很多开发者都会关注的事&#xff0c;但是有些对区块链并非十分熟悉的开发者可能会感到没有头绪。长安链提供了性能分析工具帮助开发者梳理系统耗时&#xff0c;优化系统性能。下面对长安链性能分析工具原理及使用进行介绍。 一、 概述 time_counter.s…

Windows兼容性设置图文教程,Windows兼容模式怎么设置?服务器兼容是什么意思?服务器兼容性怎么改?

兼容性&#xff08;compatibility&#xff09;是指硬件之间、软件之间或是软硬件组合系统之间的相互协调工作的程度。兼容的概念比较广&#xff0c;相对于硬件来说&#xff0c;几种不同的电脑部件&#xff0c;如CPU、主板、显示卡等&#xff0c;如果在工作时能够相互配合、稳定…

备战秋招004(20230706)

文章目录 前言一、今天学习了什么&#xff1f;二、关于问题的答案1.SE 总结 前言 提示&#xff1a;这里为每天自己的学习内容心情总结&#xff1b; Learn By Doing&#xff0c;Now or Never&#xff0c;Writing is organized thinking. 目前的想法是&#xff0c;根据 Java G…

三种方法将视频转换为AVI格式,与大家分享!

将视频转换为AVI格式是常见的需求&#xff0c;因为AVI格式具有广泛的兼容性和可编辑性。本文将介绍三种常用的方法&#xff0c;包括记灵在线工具、剪映和格式工厂。这些方法简单易行&#xff0c;帮助您将视频文件快速转换为AVI格式&#xff0c;满足不同的需求。 方法一&#x…

EasyCVR接入大量设备级联后出现分组加载异常是什么原因?

EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。 有用…

接口自动化测试实战之pytest框架+allure讲解

一、前言 本文章主要会讲解Python中pytest框架的讲解&#xff0c;介绍什么是pytest、为何要测试、为何使用以及参考和扩展等等&#xff0c;话不多说&#xff0c;咱们直接进入主题哟。 二、pytest讲解 2.1 什么是pytest&#xff1f; pytest是一款单元测试框架&#xff0c;在…

尚硅谷Docker实战教程-笔记10【高级篇,Docker微服务实战】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

浅析住宅小区电动车充电桩的电气设计与平台管理系统

安科瑞电气股份有限公司 上海嘉定201801 摘要&#xff1a;根据目前对于新能源汽车发展规划及政策&#xff0c;以及国内外充电设施的主要类型和技术参数。论述地下车库电动汽车充电桩的供配电系统的设计及设计过程中需要注意的一些问题。 关键词&#xff1a;充电桩&#xff1b…

力扣题库刷题笔记36--有效的数独

1、题目如下&#xff1a; 2、个人Python代码实现如下&#xff1a; 3、个人Python代码思路&#xff1a; 先放一个AI解释的思路&#xff1a; 个人理解&#xff0c;本题思路其实很简单&#xff0c;判断每一行、每一列、每一个3*3的子数独是否存在重复数字&#xff0c;如果存在则返…

不用转化器把pdf转化成Excel,分享两个实用方法!

将PDF文件转换为Excel格式通常是进行数据提取和分析的重要步骤。尽管市面上有许多PDF转Excel的工具&#xff0c;但本文将介绍两种无需使用转换器的实用方法&#xff0c;分别是复制粘贴法和使用记灵在线工具。这些方法简单易行&#xff0c;帮助您快速将PDF中的数据提取到Excel表…

第21章:索引优化与查询优化

一、索引优化与查询优化 1.什么情况下要进行数据库调优 ①索引失效&#xff0c;没有充分利用到索引---索引建立 ②关联查询太多join---SQL优化 ③服务器调优和各个参数的设置---调整my.cnf ④数据过多---分库分表 2.SQL优化的技术 ①物理查询优化&#xff1a;通过索引和…

图论算法:DFS求有向图或无向图两点间所有路径及Dijkstra算法求最短路径

1、目的 1)根据有向图获取指定起终点的所有路径; 2)直接求解两点间最短路径。 2、示例效果 2.1 原始数据 路线起终点整理如下: // 共计12个顶点,19条边。 (起点,终点,1)最后的1代表起点终点是连通的。 起点,终点,1:2 4 1 起点,终点,1:9 10 1 起点,终点,1:…

Java面向对象程序开发——网络编程入门知识

​ 文章目录 软件结构网络通信协议协议分类网络编程三要素TCP通信程序概述Socket类构造方法成员方法 ServerSocket类构造方法成员方法 简单的TCP网络程序客户端向服务器发送数据服务器端 文件上传服务端实现&#xff1a;客户端实现&#xff1a; BIO 、 NIO 与 AIO 软件结构 C…

Unity3D如何在一个项目建多个场景

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 设置多个场景 您可以添加多个场景、编辑查看场景的方式以及更改场景设置。 要创建新场景&#xff0c;请参阅创建、加载和保存场景。 添加场景 有两种方法可以向项目添加新场景&…

react—路由

1. 注册路由 路由的注册和vue框架中类似&#xff0c;注册过后需要在地址栏输入你想要进去的页面。 // 引入 import { createRoot } from "react-dom/client"; import { createBrowserRouter,RouterProvider,Route,Link }from "react-router-dom"; // 引入…

springboot分组校验

1、分组校验场景 主要2个场景&#xff0c;场景1&#xff1a;多个接口使用相同的入参&#xff0c;不同接口需要校验的内容不同。场景2&#xff1a;针对同一个接口&#xff0c;某个值&#xff08;一般是类型&#xff09;的不同会影响其他值的内容&#xff0c;此时需要根据某个值的…

【Linux】设置 命令 --help 帮助文件为中文

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录 前言设置系统默认语言为中文安装man-…

【C#】并行编程实战:使用 PLINQ(2)

PLINQ 是语言集成查询&#xff08;Language Integrate Query , LINQ&#xff09;的并行实现&#xff08;P 表示并行&#xff09;。本章将继续介绍其编程的各个方面以及与之相关的一些优缺点。 本文的主要内容为 PLINQ 中的合并选项以及抛出和处理异常。 本教程对应学习工程&…

Xshell连接不上虚拟机的解决办法(给他最后一次机会)

VM还原默认设置 如果你之前的操作都没问题的话Xshell还是连接不上我们的虚拟机&#xff0c;可以试试这个方法 点VM中的 编辑–>虚拟网络编辑器–还原默认设置**(这个方法也特别有效)** 注意还原好以后我们主要看一下VM8的 这是没还原之前的NAT设置 没还原之前的DHCP设置…

如何在Windows 10中创建引导到UEFI固件设置的快捷方式

大多数计算机都有一个特定的键,当计算机启动时按下该键,用户可以访问UEFI(固件)设置。然而,我们经常在错过给定的时间段时按键太晚,因为笔记本电脑默认情况下只需等待几秒钟就可以启动到 Windows。 另一个引导到 UEFI 设置的选项是重新启动到高级启动选项,然后从那里开…