Java根據(jù)分組key構(gòu)建合并數(shù)據(jù)集的代碼詳解
背景
Java 需要返回一組數(shù)據(jù)供前端展示,獲取到的數(shù)據(jù)格式如下:
List<Map<String, Object>> varSummary 存在多組數(shù)據(jù),varSummary中map結(jié)構(gòu)一致
[{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=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=其他, marital_state=3}]
需求一:
已知需要合并分組的屬性有:sub_product_name、approval_result、varSummary中的數(shù)據(jù),需要構(gòu)建合并對象屬性
核心邏輯說明:
- 雙層分組處理:
外層分組:按 sub_product_name 分組(示例中3條數(shù)據(jù)均相同)
內(nèi)層分組:在外層分組內(nèi)按 approval_result 分組(示例中前兩條"其它"相同,第三條"通過"不同)
- 合并規(guī)則:
第一列(col=0):合并相同 sub_product_name 的行(rowspan=3)
第二列(col=1):合并相同 approval_result 的連續(xù)行(rowspan=2)
# 參數(shù)說明:
{
"colspan": 1,// 合并列數(shù)(固定為1)
"col": 0, //起始第N列
"rowspan": 3//合并行數(shù)
"row": 0, //起始第N行
}
#輸出對象數(shù)據(jù):
{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 {
/**
* .
* 構(gòu)建返回對象
*
* @param varSummary 原始數(shù)據(jù)
* @param targetColumns 動態(tài)指定需要合并的值
* @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++) {
// 檢查每列是否需要結(jié)束當前分組
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;
}
// 當外層列值變化時,重置內(nèi)層列的分組
for (int innerCol = col + 1; innerCol < targetColumns.size(); innerCol++) {
groupStarts[innerCol] = row;
if (row < n) {
currentValues[innerCol] = getStringValue(varSummary.get(row), targetColumns.get(innerCol));
}
}
// 跳出內(nèi)層列循環(huán),避免重復處理
break;
}
}
}
return result;
}
/**
* .
* 構(gòu)建輸出對象
*
* @param row 起始行
* @param col 起始列
* @param rowspan 合并行數(shù)
* @param colspan 合并列數(shù)(固定值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) {
// 示例數(shù)據(jù)構(gòu)造
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", "生活費-聯(lián)合貸");
map4.put("approval_result", "通過");
map4.put("marital_state", 3);
varSummary.add(map4);
Map<String, Object> map5 = new HashMap<>();
map5.put("sub_product_name", "生活費-聯(lián)合貸");
map5.put("approval_result", "通過");
map5.put("marital_state", 3);
varSummary.add(map5);
Map<String, Object> map6 = new HashMap<>();
map6.put("sub_product_name", "生活費-聯(lián)合貸");
map6.put("approval_result", "通過");
map6.put("marital_state", 3);
varSummary.add(map6);
Map<String, Object> map7 = new HashMap<>();
map7.put("sub_product_name", "生活費-聯(lián)合貸");
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);
// 輸出結(jié)果
for (Map<String, Integer> cell : mergeInfo) {
System.out.println(cell);
}
/* 原始數(shù)據(jù)格式
[{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=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=通過, marital_state=3},
{sub_product_name=生活費-聯(lián)合貸, approval_result=其他, marital_state=3}]
構(gòu)建輸出對象
{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}*/
}
總結(jié)
到此這篇關(guān)于Java根據(jù)分組key構(gòu)建合并數(shù)據(jù)集的代碼詳解的文章就介紹到這了,更多相關(guān)Java根據(jù)key構(gòu)建數(shù)據(jù)集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot ResponseBody返回值處理的實現(xiàn)
這篇文章主要介紹了SpringBoot ResponseBody返回值處理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
阿里面試Nacos配置中心交互模型是push還是pull原理解析
這篇文章主要為大家介紹了阿里面試Nacos配置中心交互模型是push還是pull原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07
詳解Java中的有參構(gòu)造方法與無參構(gòu)造方法
這篇文章主要詳細介紹了Java中有參構(gòu)造方法與無參構(gòu)造方法,文中有詳細的代碼示例,讓大家清晰明了的了解到有參構(gòu)造方法與無參構(gòu)造方法、以及應(yīng)用,需要的朋友可以參考下2023-06-06
logback的AsyncAppender高效日志處理方式源碼解析
這篇文章主要為大家介紹了logback的AsyncAppender高效日志處理方式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10
mybatis.type-aliases-package之巨坑的解決
這篇文章主要介紹了mybatis.type-aliases-package之巨坑的解決,具有很好的參考價值,希望對大家有所幫助。2021-09-09
Intellij?IDEA根據(jù)maven依賴名查找它是哪個pom.xml引入的(圖文詳解)
這篇文章主要介紹了Intellij?IDEA根據(jù)maven依賴名查找它是哪個pom.xml引入的,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
SpringBoot 并發(fā)登錄人數(shù)控制的實現(xiàn)方法
這篇文章主要介紹了SpringBoot 并發(fā)登錄人數(shù)控制的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-05-05

