Java 根据分组key构建合并数据集

文章目录

  • 前言
  • 背景
  • 总结


前言

请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、


提示:以下是本篇文章正文内容,下面案例可供参考

背景

Java 需要返回一组数据供前端展示,获取到的数据格式如下:
List<Map<String, Object>> varSummary 存在多组数据,varSummary中map结构一致

[{sub_product_name=生活费-生意贷, approval_result=其它, marital_state=3},{sub_product_name=生活费-生意贷, approval_result=其它, marital_state=3}, {sub_product_name=生活费-生意贷, approval_result=通过, marital_state=3},{sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3}, {sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3}, {sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3}, {sub_product_name=生活费-联合贷, approval_result=其他, marital_state=3}]

需求一:
已知需要合并分组的属性有:sub_product_name、approval_result、varSummary中的数据,需要构建合并对象属性

核心逻辑说明:

  1. 双层分组处理:

外层分组:按 sub_product_name 分组(示例中3条数据均相同)

内层分组:在外层分组内按 approval_result 分组(示例中前两条"其它"相同,第三条"通过"不同)

  1. 合并规则:

第一列(col=0):合并相同 sub_product_name 的行(rowspan=3)

第二列(col=1):合并相同 approval_result 的连续行(rowspan=2)

# 参数说明:
{"colspan": 1,// 合并列数(固定为1)"col": 0, //起始第N列"rowspan":  3//合并行数"row": 0, //起始第N行
}#输出对象数据:
{colspan=1, col=0, rowspan=3, row=0},
{colspan=1, col=0, rowspan=4, row=3},
{colspan=1, col=1, rowspan=2, row=0},
{colspan=1, col=1, rowspan=3, row=3}

核心代码逻辑:

import com.wiseco.model.mgt.server.web.vo.resp.ReportOutputDto;import java.util.*;public class MergeCells {/*** .* 构建返回对象** @param varSummary    原始数据* @param targetColumns 动态指定需要合并的值* @return*/public static List<Map<String, Integer>> buildMergeInfo(List<Map<String, Object>> varSummary,List<String> targetColumns) {List<Map<String, Integer>> result = new ArrayList<>();if (varSummary == null || varSummary.isEmpty() || targetColumns == null || targetColumns.isEmpty()) {return result;}int n = varSummary.size();int[] groupStarts = new int[targetColumns.size()];  // 每列当前分组的起始行索引String[] currentValues = new String[targetColumns.size()];  // 每列当前分组的值// 初始化第一行的值for (int col = 0; col < targetColumns.size(); col++) {currentValues[col] = getStringValue(varSummary.get(0), targetColumns.get(col));}// 遍历每一行(从第1行开始)for (int row = 1; row <= n; row++) {// 检查每列是否需要结束当前分组for (int col = 0; col < targetColumns.size(); col++) {String currentVal = (row < n) ?getStringValue(varSummary.get(row), targetColumns.get(col)) :null;// 如果列值变化或是最后一行boolean valueChanged = row < n && !Objects.equals(currentVal, currentValues[col]);if (valueChanged || row == n) {int groupSize = row - groupStarts[col];if (groupSize > 1) {result.add(createCellInfo(groupStarts[col], col, groupSize, 1));}// 更新当前分组起始位置groupStarts[col] = row;// 重置当前值if (row < n) {currentValues[col] = currentVal;}// 当外层列值变化时,重置内层列的分组for (int innerCol = col + 1; innerCol < targetColumns.size(); innerCol++) {groupStarts[innerCol] = row;if (row < n) {currentValues[innerCol] = getStringValue(varSummary.get(row), targetColumns.get(innerCol));}}// 跳出内层列循环,避免重复处理break;}}}return result;}/*** .* 构建输出对象** @param row     起始行* @param col     起始列* @param rowspan 合并行数* @param colspan 合并列数(固定值1)* @return*/private static Map<String, Integer> createCellInfo(int row, int col, int rowspan, int colspan) {Map<String, Integer> cell = new HashMap<>();cell.put("row", row);cell.put("col", col);cell.put("rowspan", rowspan);cell.put("colspan", colspan);return cell;}private static String getStringValue(Map<String, Object> map, String key) {Object value = map.get(key);return (value != null) ? value.toString() : null;}}

测试案例:

public static void main(String[] args) {// 示例数据构造List<Map<String, Object>> varSummary = new ArrayList<>();Map<String, Object> map1 = new HashMap<>();map1.put("sub_product_name", "生活费-生意贷");map1.put("approval_result", "其它");map1.put("marital_state", 3);varSummary.add(map1);Map<String, Object> map2 = new HashMap<>();map2.put("sub_product_name", "生活费-生意贷");map2.put("approval_result", "其它");map2.put("marital_state", 3);varSummary.add(map2);Map<String, Object> map3 = new HashMap<>();map3.put("sub_product_name", "生活费-生意贷");map3.put("approval_result", "通过");map3.put("marital_state", 3);varSummary.add(map3);Map<String, Object> map4 = new HashMap<>();map4.put("sub_product_name", "生活费-联合贷");map4.put("approval_result", "通过");map4.put("marital_state", 3);varSummary.add(map4);Map<String, Object> map5 = new HashMap<>();map5.put("sub_product_name", "生活费-联合贷");map5.put("approval_result", "通过");map5.put("marital_state", 3);varSummary.add(map5);Map<String, Object> map6 = new HashMap<>();map6.put("sub_product_name", "生活费-联合贷");map6.put("approval_result", "通过");map6.put("marital_state", 3);varSummary.add(map6);Map<String, Object> map7 = new HashMap<>();map7.put("sub_product_name", "生活费-联合贷");map7.put("approval_result", "其他");map7.put("marital_state", 3);varSummary.add(map7);// 生成合并信息List<String> targetColumns = Arrays.asList("marital_state","sub_product_name");List<Map<String, Integer>> mergeInfo = buildMergeInfo(varSummary, targetColumns);System.out.println(varSummary);// 输出结果for (Map<String, Integer> cell : mergeInfo) {System.out.println(cell);}/* 原始数据格式[{sub_product_name=生活费-生意贷, approval_result=其它, marital_state=3},{sub_product_name=生活费-生意贷, approval_result=其它, marital_state=3},{sub_product_name=生活费-生意贷, approval_result=通过, marital_state=3},{sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3},{sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3},{sub_product_name=生活费-联合贷, approval_result=通过, marital_state=3},{sub_product_name=生活费-联合贷, approval_result=其他, marital_state=3}]构建输出对象{colspan=1, col=0, rowspan=3, row=0}{colspan=1, col=0, rowspan=4, row=3}{colspan=1, col=1, rowspan=2, row=0}{colspan=1, col=1, rowspan=3, row=3}*/}

总结

我是南国以南i记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!

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

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

相关文章

Linux平台Oracle开机自启动设置

网上和官方文档已经有不少介绍如何设置开机启动Oracle实例的文章(Linux平台)&#xff0c;不过以sysvinit和service这种方式居多。最近遇到了UAT环境的服务器打补丁后需要重启服务器的情况&#xff0c; 需要DBA去手工启动Oracle实例的情形&#xff0c;和同事讨论&#xff0c;决定…

商品中心—商品B端搜索系统的实现文档(二)

8.步骤四&#xff1a;基于索引实现搜索功能 (1)基于suggest索引的自动补全实现 实现自动补全的代码比较简单&#xff0c;其原理是&#xff1a;把搜索词汇和倒排索引里的所有前缀匹配的词条进行score比较&#xff0c;然后把分数最高的那些返回&#xff0c;其中会涉及到suggest索…

Codeforces Round 1027 (Div. 3)

A. Square Year 题目大意 给你一个四个字符的字符串&#xff0c;代表一个数字s 问是否存在a,b两个数字&#xff0c;使得 ( a b ) 2 s (ab)^2s (ab)2s 思路 如果s是奇数或不能被开根号一定不行 设sq为s开根号后的结果 将sq一分为2&#xff0c;考虑sq/2有没有余数的情况 //…

时序数据库IoTDB的架构、安装启动方法与数据模式总结

一、IoTDB的架构 IoTDB的架构主要分为三个部分&#xff1a; ‌时序文件&#xff08;Tsfile&#xff09;‌&#xff1a; 专为时序数据设计的文件存储格式。支持高效的压缩和查询性能。可独立使用&#xff0c;并可通过TsFileSync工具同步至HDFS进行大数据处理。 ‌数据库引擎‌…

ArrayList和LinkedList详解

在Java后端开发中&#xff0c;集合框架是我们日常编程不可或缺的工具&#xff0c;它为数据存储和操作提供了丰富的实现方式。作为Java集合框架中最常用的两种List实现&#xff0c;ArrayList和LinkedList各自具有独特的特性和适用场景。 1. 基本概念 1.1 ArrayList的定义与特性…

警惕微软Entra ID风险:访客账户存在隐蔽的权限提升策略

访客用户订阅权限漏洞解析 微软Entra ID的订阅管理存在访问控制缺陷&#xff0c;允许访客用户在受邀租户中创建和转移订阅&#xff0c;同时保留对这些订阅的完全所有权。访客用户只需具备在源租户创建订阅的权限&#xff0c;以及受邀成为外部租户访客的身份即可实施此操作。这…

EEG分类攻略2-Welch 周期图

在EEG信号处理的上下文中&#xff0c;使用Welch方法来估算信号的功率谱密度&#xff08;Power Spectral Density, PSD&#xff09;是一种常见的做法。你的代码片段是利用**scipy.signal.welch**函数来进行功率谱密度估算&#xff0c;并且涉及到一些关键的参数和步骤。让我们逐步…

开疆智能CCLinkIE转ModbusTCP网关连接脉冲计数器配置案例

本案例是三菱PLC通过CCLinkIE转ModbusTCP网关连接脉冲计数器的配置案例&#xff0c;具体配置如下。 配置过程&#xff1a; 首先设置从站通讯参数 主要设置IP地址&#xff0c;工作模式以及端口号&#xff08;Modbus默认502&#xff09; 找到通讯点表&#xff0c;找到需要读写的…

gRPC 使用(python 版本)

.proto 文件 .proto 文件 是 gRPC 和 Protocol Buffers 的接口定义文件&#xff0c;它描述了&#xff1a; 要传递什么数据&#xff08;也就是消息体 message&#xff09;。要暴露什么接口&#xff08;也就是服务 service 和它们的 方法&#xff09;。 也就是一份规范文件&am…

VMware安装

勾选【增强型键盘驱动程序】 #后期虚拟机用鼠标键盘比较好用 VMware创建主机Windows2 选择类型配置【自定义】 安装客户机操作系统【稍后安装操作系统】 客户机操作系统【Microsoft Windows】,版本选Windows最高版本 【固件类型】默认UEFI 【处理器配置】选1个处理…

【沉浸式解决问题】微服务子模块引入公共模块的依赖后无法bean未注入

目录 一、问题描述二、场景还原三、原因分析四、解决方案五、拓展知识参考文献 一、问题描述 在微服务项目中的公共模块进行了Mybatis Plus配置&#xff0c;创建了配置类并添加了Configuration注解&#xff0c;其他模块引入该模块后不生效 我这里是在Mybatis Plus公共模块中注…

SQL进阶:CASE表达式

目录 1、用一条SQL语句进行不同条件的统计 建表语句&#xff08;MySQL8&#xff09;&#xff1a; 录入数据&#xff1a; *按性别统计SQL 输出结果&#xff08;行列转换&#xff09; 2、在UPDATE语句里进行条件分支 建表语句&#xff08;MySQL8&#xff09;&#xff1a;…

哪四款AI工具让3D人物手办制作如此简单?

在当今数字化时代&#xff0c;AI技术的飞速发展为我们的生活带来了诸多便利和惊喜。其中&#xff0c;AI生成3D人物手办工具的出现&#xff0c;让我们能够轻松地将自己的创意和想象转化为实体手办&#xff0c;满足了众多手办爱好者的个性化需求。今天&#xff0c;我将为大家推荐…

Docker高级管理--Dockerfile镜像制作

目录 一:Docker 镜像管理 1:Docker 镜像结构 2:Dockerfile介绍 二:Dockerfile 语法基础 1:基础指令 2:环境设置指令 3:文件操作指令 4:执行命令指令 5:网络和暴露端口指令 6.容器挂载指令 三&#xff1a;dockerfile案例 1.构建nginx容器 一:Docker 镜像管理 Docker…

数字时代的“灵魂”之争:虚拟人形象的著作权困局与破局之道

首席数据官高鹏律师数字经济团队创作&#xff0c;AI辅助。 一、虚拟人的“数字生命”&#xff1a;一场关于“灵魂”的商业博弈 当一个虚拟偶像的“眼神”被复刻成千万个相似的数字面孔&#xff0c;当一段虚拟主播的“声音”被拆解为可交易的数据碎片——我们正在见证一个“数…

小型CI/CD搭建(TODO)

1 方案 因为是在国内&#xff0c;所以gitbub Actions&#xff0c;​​Azure DevOps​这些就直接拜拜了。 目前主流的大概是三种&#xff1a; 1 阿里云效/腾讯云CODING 2 GitLab CE GitLab Runner 3 Gitee Jenkins deepeseek比较了一下如下&#xff1a; 阿里云效 vs Git…

Android Studio flutter项目运行、打包时间太长

Android Studio&#xff1a;Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1 flutter Sdk&#xff1a;3.29.3 系统&#xff1a;windows flutter sdk从2.10.5升级到3.29.3&#xff0c;但是Flutter 3.16开始新增了使用 Gradle声明式 plugins {} 块&#xff0c;gradle文…

【OpenGL学习】(六)图形添加纹理

文章目录 【OpenGL学习】&#xff08;六&#xff09;图形添加纹理纹理环绕纹理过滤纹理颜色与顶点颜色混合 OpenGL纹理介绍&#xff1a;https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 【OpenGL学习】&#xff08;六&#xff09;图形添加纹理 项目…

allure安装

一、安装java 需要安装java环境&#xff0c;不安装的话在运行前会报错下列问题&#xff08;前提是安装了allure未安装java&#xff09; 1.官网地址&#xff1a;https://www.oracle.com/ 2.点击”Download Java“ 3.选择JDK正式版本&#xff08;需要jdk1.8&#xff09; 4.选择W…

SpringBoot基于JavaWeb的城乡居民基本医疗信息管理系统

概述 一个基于SpringBoot框架开发的JavaWeb医疗信息管理系统&#xff0c;采用了现代化的技术架构&#xff0c;功能全面&#xff0c;非常适合作为学习项目或二次开发的基础。 主要内容 该系统主要包含以下核心功能模块&#xff1a; ​​用户管理模块​​ 实现管理员、医生、…