You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并DB获取的ScheduleActionDispatchDTO列表同项的request_json

问题描述

从数据库获取待处理调度列表:

List<ScheduleActionDispatchDTO> pendingScheduleActions 
= restClientApi.getPendingSchedules();

数据示例

schedule_request_id = 576, user_id = 24, 
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00', 
request_json = '{"testId": "5", "grade": "A"}'

schedule_request_id = 576, user_id = 24, 
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00', 
request_json = '{"subjectId": "10", "name": "dictation"}'

schedule_request_id = 577, user_id = 24, start_time_utc = '2022-12-17 21:00:00', 
end_time_utc = '2022-12-18 01:00:00', request_json = '{"testId": "5", "grade": "A"}'

需求

当列表中任意行的schedule_request_id、user_id、start_time_utc和end_time_utc字段值完全相同时,将这些行的request_json值合并。合并后的预期结果如下:

合并结果1

schedule_request_id = 576, user_id = 24, 
start_time_utc = '2022-12-16 21:00:00', end_time_utc = '2022-12-17 01:00:00', 
combinedResult = '[{"testId": "5", "grade": "A"}, {"subjectId": "10", "name": "dictation"}]'

合并结果2

schedule_request_id = 577, user_id = 24, start_time_utc = '2022-12-17 21:00:00', 
end_time_utc = '2022-12-18 01:00:00', combinedResult = '{"testId": "5", "grade": "A"}'

已尝试的代码

目前完成了初步分组,但不清楚后续合并逻辑:

Map<Long, List<ScheduleActionDispatchDTO>> requestMap = pendingScheduleActions.stream()
                    .collect(Collectors.groupingBy(
                            ScheduleActionDispatchDTO::getScheduleRequestId, Collectors.toList()));

for (Map.Entry<Long, List<ScheduleActionDispatchDTO>> entry : requestMap.entrySet()) {
   List<ScheduleActionDispatchDTO> sameRequestActions = entry.getValue();
   Map<ScheduleActionDispatchPair, ScheduleActionDispatchDTO> schedulePairAction =
                            sameRequestActions.stream().
                            collect(Collectors.toMap(
                            s -> new ScheduleActionDispatchPair(s.getScheduleRequestId(), s.getUserId(), s.getStartTimeUtc(), s.getEndTimeUtc()),
                            s -> s));

// 不知道如何继续完成合并
}

解决方案

步骤1:确保分组键的正确性

首先要保证ScheduleActionDispatchPair类正确重写了equals()和hashCode()方法,让schedule_request_id、user_id、start_time_utc、end_time_utc四个字段都参与相等性判断,这样才能作为Map的键实现正确分组。

步骤2:直接按完整条件分组

无需先按schedule_request_id拆分,直接用ScheduleActionDispatchPair作为分组键,一步完成同条件数据的聚合:

// 按四个字段分组,每组是符合条件的DTO列表
Map<ScheduleActionDispatchPair, List<ScheduleActionDispatchDTO>> groupedByKey = pendingScheduleActions.stream()
    .collect(Collectors.groupingBy(
        s -> new ScheduleActionDispatchPair(
            s.getScheduleRequestId(), 
            s.getUserId(), 
            s.getStartTimeUtc(), 
            s.getEndTimeUtc()
        )
    ));

步骤3:合并request_json并生成结果

遍历分组后的Map,借助JSON工具类(如Jackson或Gson)解析和生成JSON,避免手动拼接出错:

示例代码(使用Jackson)

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, Object>> finalResults = new ArrayList<>();

for (Map.Entry<ScheduleActionDispatchPair, List<ScheduleActionDispatchDTO>> entry : groupedByKey.entrySet()) {
    ScheduleActionDispatchPair key = entry.getKey();
    List<ScheduleActionDispatchDTO> dtoList = entry.getValue();
    
    // 解析所有request_json为对象
    List<Object> jsonItems = new ArrayList<>();
    for (ScheduleActionDispatchDTO dto : dtoList) {
        try {
            Map<String, Object> jsonObj = objectMapper.readValue(dto.getRequestJson(), new TypeReference<>() {});
            jsonItems.add(jsonObj);
        } catch (Exception e) {
            // 处理JSON解析异常
            e.printStackTrace();
        }
    }
    
    // 生成合并后的JSON字符串
    String combinedResult;
    if (jsonItems.size() == 1) {
        // 单条数据直接输出原格式
        try {
            combinedResult = objectMapper.writeValueAsString(jsonItems.get(0));
        } catch (Exception e) {
            combinedResult = dtoList.get(0).getRequestJson();
        }
    } else {
        // 多条数据生成JSON数组
        try {
            combinedResult = objectMapper.writeValueAsString(jsonItems);
        } catch (Exception e) {
            combinedResult = "[]";
        }
    }
    
    // 组装结果(可按需转为自定义DTO)
    Map<String, Object> result = new HashMap<>();
    result.put("schedule_request_id", key.getScheduleRequestId());
    result.put("user_id", key.getUserId());
    result.put("start_time_utc", key.getStartTimeUtc());
    result.put("end_time_utc", key.getEndTimeUtc());
    result.put("combinedResult", combinedResult);
    
    finalResults.add(result);
}

步骤4:可选 - 封装为自定义DTO

如果需要结构化结果,可以创建CombinedScheduleResultDTO类,替换上述的Map<String, Object>:

public class CombinedScheduleResultDTO {
    private Long scheduleRequestId;
    private Long userId;
    private String startTimeUtc;
    private String endTimeUtc;
    private String combinedResult;
    
    // 构造方法、getter、setter
}

然后在循环中创建DTO实例:

CombinedScheduleResultDTO resultDTO = new CombinedScheduleResultDTO();
resultDTO.setScheduleRequestId(key.getScheduleRequestId());
resultDTO.setUserId(key.getUserId());
resultDTO.setStartTimeUtc(key.getStartTimeUtc());
resultDTO.setEndTimeUtc(key.getEndTimeUtc());
resultDTO.setCombinedResult(combinedResult);
finalResults.add(resultDTO);

内容的提问来源于stack exchange,提问作者sjain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:50:21