java 中的 list 如何聚合并转换类型为Map包Map里面在处理为其他类型, 如何使用 Collectors.groupingBy Collectors.collectingAndThen
已于 2022-11-03 16:59:56 修改
2020-09-17 16:21:33
有一个
List<RecipeCalendar>
,数据库中查询出来的列表,需要聚合并转换类型为一个map:
Map<String, Map<Integer, RecipeCalendarInfoVO>>
这里的key是日期(
RecipeCalendar.recipeDate格式yyyy-MM-dd
),value是当日(早,中,晚)的食谱区间map;
食谱区间map(
Map<Integer, RecipeCalendarInfoVO>
)的key是10.早餐 20.中餐 30.晚餐(RecipeCalendar.intervalType), value是实际的食谱详细信息(
RecipeCalendarInfoVO(内容参考类信息)
)
RecipeCalendar类(省略get,set方法):
@Data
public class RecipeCalendar extends Model<RecipeCalendar> {
private static final long serialVersionUID = 1L;
* 食谱日历 主键
@TableId(value = "id", type = IdType.AUTO)
private Long id;
* 患者唯一编号
private Long patientFileId;
* 租户ID
@TableField(fill = FieldFill.INSERT)
private Long tenantId;
* 员工id
private Long employeeId;
* 员工姓名
private String employeeName;
* 食谱ID
private Long recipeId;
* 日期区间 10.早餐 20.中餐 30.晚餐
private Integer intervalType;
* 食谱日历日期 格式 YYYY-MM-DD,范围 1000-01-01/9999-12-31
private Date recipeDate;
* 食谱名称
private String recipeName;
* 食谱热量(kcal)
private Integer calories;
RecipeCalendarInfoVO类(省略get,set方法):
@Data
public class RecipeCalendarInfoVO{
@ApiModelProperty("食谱总热量(sum(RecipeCalendar.calories))")
private Integer calories;
@ApiModelProperty("食谱列表")
private List<RecipeCalendar> recipeCalendarList;
聚合并转换类型(使用Collectors.groupingBy和Collectors.collectingAndThen):
// 集合不为空
List<RecipeCalendar> list;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 数据聚合转换
Map<String, Map<Integer, RecipeCalendarInfoVO>> recipeCalendarDateMap = list.stream()
.collect(
// 根据日期聚合
Collectors.groupingBy(recipeCalendar -> simpleDateFormat.format(recipeCalendar.getRecipeDate()),
// 保持顺序,用LinkedHashMap::new
LinkedHashMap::new,
// 根据日期区间(早,中,晚)聚合第二层
Collectors.groupingBy(RecipeCalendar::getIntervalType,
// 保持顺序,用LinkedHashMap::new
LinkedHashMap::new,
// 处理内层list 转换为 RecipeCalendarInfoVO
Collectors.collectingAndThen(Collectors.toList(), recipeCalendars -> {
RecipeCalendarInfoVO recipeCalendarInfoVO = new RecipeCalendarInfoVO();
recipeCalendarInfoVO.setCalories(recipeCalendars.stream().mapToInt(recipeCalendar -> recipeCalendar.getCalories() == null ? 0 : recipeCalendar.getCalories()).sum());
recipeCalendarInfoVO.setRecipeCalendarList(recipeCalendars);
return recipeCalendarInfoVO;
))));
return recipeCalendarDateMap;