如何基于CustomObject字段排序<String,List<CustomObject>>类型Map?
按分组内作业进度排序教师作业分组(Java Stream实现)
核心解决方案代码
Map<String, List<Assignmentsdata>> sortedResult = liveAssignments.stream() // 原分组逻辑 .collect(Collectors.groupingBy(Assignmentsdata::getTeacherId)) // 转为entry流进行排序 .entrySet() .stream() .sorted((entry1, entry2) -> { // 判断分组是否存在进度为0的作业 boolean hasZeroProgress1 = entry1.getValue().stream() .anyMatch(assignment -> assignment.getProgress() == 0); boolean hasZeroProgress2 = entry2.getValue().stream() .anyMatch(assignment -> assignment.getProgress() == 0); // 存在0进度作业的分组优先排在前面 if (hasZeroProgress1 != hasZeroProgress2) { return hasZeroProgress1 ? -1 : 1; } // 无0进度的分组,按totalCompletedAssignments总和排序(可按需调整逻辑) int totalCompleted1 = entry1.getValue().stream() .mapToInt(Assignmentsdata::getTotalCompletedAssignments) .sum(); int totalCompleted2 = entry2.getValue().stream() .mapToInt(Assignmentsdata::getTotalCompletedAssignments) .sum(); return Integer.compare(totalCompleted1, totalCompleted2); }) // 收集为有序LinkedHashMap,保留排序结果 .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldVal, newVal) -> oldVal, LinkedHashMap::new ));
逻辑说明
- 基础分组:保留你原本的
groupingBy逻辑,先按teacherId完成作业归类。 - 排序规则:
- 第一优先级:只要分组内存在任意进度为0的作业,直接将该分组排到最前面。
- 次优先级:若两个分组都有/都没有0进度作业,则按分组内所有作业的
totalCompletedAssignments总和排序(你可根据需求调整聚合方式,比如取最大值、最小值,或改为降序排序)。
- 有序存储:用
LinkedHashMap收集结果,确保排序后的分组顺序不会丢失。
对应你的示例
你的示例中TeacherB的分组包含进度为0的作业,排序时会被优先放到首位,最终输出顺序与你期望的完全一致。
内容的提问来源于stack exchange,提问作者Ifan 767
相关产品推荐
相关产品推荐

