利用Stream流通过时间段与表名称两个维度计算表得分

业务需求是需要做一个对某个人所有评估表中的数据进行一个统计的功能,其中可以选择评估表与时间段来观察某个人具体在何时进行评估并且算出相应得分。因为业务场景较为复杂则将模板与评估表分开存储,且评估实例中有属性:得分、时间点、模板编号;模板表中有属性:模板编号、模板名称。首先我们最终需要构造如下数据通过接口输出:

{
    "columns": [
        "日期",
        "出血风险评估2.0",
        "VTE风险评估2.0"
    ],
    "rows": [
        {
            "日期": "2022-06-16 11:17:19",
            "VTE风险评估2.0": 20,
            "出血风险评估2.0": 0
        },
        {
            "日期": "2022-06-16 11:17:33",
            "VTE风险评估2.0": 20,
            "出血风险评估2.0": 0
        },
        {
            "日期": "2022-06-16 11:18:25",
            "出血风险评估2.0": 16,
            "VTE风险评估2.0": 0
        }
    ]
}

第一步先将模板编号与模板名称对应起来:

Map<String, String> tempMap = templateEntities.stream().collect(Collectors.toMap(EvaluationFormTemplateEntity::getId, EvaluationFormTemplateEntity::getFormName));

而后把评估表根据时间分一下组:

 Map<String, List<EvaluationFormInstanceEntity>> groupedEvaIns1 =
                histEv.stream().sorted(Comparator.comparing(EvaluationFormInstanceEntity::getCreateDateStr))
                     .collect(Collectors.groupingBy(EvaluationFormInstanceEntity::getCreateDateStr));

现在就处理为,编号->名称,时间->评估记录,现在处理两个参数就可以继续后续计算,选择表与时间段处理过程是表通过编号过滤即可,时间段处理为:

groupedEvaIns1 = groupedEvaIns1.entrySet().stream().filter(p -> {
                if (p.getKey().compareTo(voTime) > 0 && p.getKey().compareTo(dateStr) < 0) {
                    return Boolean.TRUE;
                } else {
                    return Boolean.FALSE;
                }
            }).collect(Collectors.toMap(
                    (e) -> (String) e.getKey(),
                    Map.Entry::getValue
            ));

map对key进行排序后进行横纵坐标数据填充:

Map<String, List<EvaluationFormInstanceEntity>> groupedEvaIns = ChangeUtils.sortMapByKey(groupedEvaIns1);

最后进行填充即可:

JSONObject ret = new JSONObject();
ret.put("rows", rowsList);
        ret.put("columns", columnList);
if(null!=groupedEvaIns) {
            groupedEvaIns.forEach((k, v) -> {
                Map<String, Object> ev = new HashMap();
                ev.put("日期", k);
                for (EvaluationFormInstanceEntity e : v) {
                    String tempTemplateId = e.getEvaluationFormReleaseId();
                    EvaluationFormReleaseEntity formRelease = evaluationFormReleaseService.findById(tempTemplateId);
                    if (null != formRelease) {
                        tempTemplateId = formRelease.getTemplateId();
                    }
                    ev.put(tempMap.get(tempTemplateId), e.getScore());
                    evaTempId.add(tempMap.get(tempTemplateId));
                }
                rowsList.add(ev);
            });
        }
        columnList.addAll(evaTempId);
        List<Map<String, Object>> res = new ArrayList<>();
        List<String> formNames = columnList.stream().filter(p -> !"日期".equals(p)).collect(Collectors.toList());
        for (Map<String, Object> map : rowsList) {
            AtomicReference<String> formNameTemp = new AtomicReference<>();
            AtomicReference<Integer> score = new AtomicReference<>(0);
            map.forEach((k,v)->{
                if(!k.equals("日期")){
                    formNameTemp.set(k);
                    score.set(Integer.parseInt(String.valueOf(v)));
                }
            });
            Map<String, Object> tempMaps = map.entrySet().stream().filter(p -> p.getKey().equals("日期")).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            formNames.forEach(p->tempMaps.put(p,0));
            tempMaps.put(formNameTemp.get(),score.get());
            res.add(tempMaps);
        }
        ret.put("rows", res);

有一说一stream流式计算还是挺方便的,下一篇一起探讨定时任务模块中,定时器轮询,MQ与时间轮处理并发问题。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Stream流可以通过filter()方法来进行过滤操作。如果要过滤时间段,可以使用LocalTime类的isAfter()和isBefore()方法来判断时间是否在指定的时间段内。下面是一个示例代码: ```java import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Test { public static void main(String[] args) { List<LocalTime> times = new ArrayList<>(); times.add(LocalTime.parse("08:00:00")); times.add(LocalTime.parse("12:00:00")); times.add(LocalTime.parse("15:30:00")); times.add(LocalTime.parse("19:00:00")); // 过滤出时间段在8点到12点之间的时间 List<LocalTime> filteredTimes = times.stream() .filter(time -> time.isAfter(LocalTime.parse("08:00:00")) && time.isBefore(LocalTime.parse("12:00:00"))) .collect(Collectors.toList()); // 输出过滤后的时间 filteredTimes.forEach(System.out::println); } } ``` 上述代码中,我们创建了一个包含多个时间的List集合,然后使用stream()方法获取流。通过filter()方法,我们可以使用isAfter()和isBefore()方法来过滤出在指定时间段内的时间。最后使用collect()方法将过滤后的时间收集到一个新的List集合中,并使用forEach()方法输出过滤后的时间。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [java8新特性—stream流、时间类](https://blog.csdn.net/weixin_48112109/article/details/125898584)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值