如何将List<Schedule>合并为MyPojo列表?JPA数据合并处理
问题描述
现有数据库表数据如下:
Id name descr type freq 1 A desc SMS daily 1 A desc Push weekly 1 A desc InAp custom 2 B desc1 SMS weekly 2 B desc1 Push daily
通过JPA将该表映射为包含id、name、desc、type、freq字段的List<Schedule>集合。需要对该集合做以下处理:
- 当
name与desc相同时,合并为一个MyPojo对象:公共字段直接赋值,不同的type和freq分别收集为列表; - 若
name或desc不同,则单独作为列表项。
MyPojo类定义如下:
class MyPojo{ private int id; private String name; private String desc; private List<String> type; private List<String> frequency; //setters and getters }
预期输出:
O/P= [{"id":"1", "name":"A", "desc":"desc", "type":["SMS","Push","InApp"], "freq":["daily","weekly","custom"]}, {"id":"2", "name":"B", "desc":"desc1", "type":["SMS","Push"], "freq":["daily","weekly"]}]
解决方案
可以通过Java Stream的分组+映射实现需求,具体代码如下:
完整实现代码
import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.AbstractMap.SimpleEntry; // 假设Schedule实体类结构(需与JPA映射一致) class Schedule { private int id; private String name; private String desc; private String type; private String freq; // 构造器、getter方法 public Schedule(int id, String name, String desc, String type, String freq) { this.id = id; this.name = name; this.desc = desc; this.type = type; this.freq = freq; } public int getId() { return id; } public String getName() { return name; } public String getDesc() { return desc; } public String getType() { return type; } public String getFreq() { return freq; } } class MyPojo{ private int id; private String name; private String desc; private List<String> type; private List<String> frequency; // 构造器、getter/setter方法 public MyPojo(int id, String name, String desc, List<String> type, List<String> frequency) { this.id = id; this.name = name; this.desc = desc; this.type = type; this.frequency = frequency; } public int getId() { return id; } public String getName() { return name; } public String getDesc() { return desc; } public List<String> getType() { return type; } public List<String> getFrequency() { return frequency; } } public class ScheduleMerger { public static void main(String[] args) { // 模拟JPA查询得到的Schedule集合 List<Schedule> schedules = List.of( new Schedule(1, "A", "desc", "SMS", "daily"), new Schedule(1, "A", "desc", "Push", "weekly"), new Schedule(1, "A", "desc", "InAp", "custom"), new Schedule(2, "B", "desc1", "SMS", "weekly"), new Schedule(2, "B", "desc1", "Push", "daily") ); // 核心处理逻辑 List<MyPojo> mergedResult = schedules.stream() // 按name+desc的组合分组,相同组合的Schedule归为一组 .collect(Collectors.groupingBy( sch -> new SimpleEntry<>(sch.getName(), sch.getDesc()), Collectors.toList() )) .values() .stream() // 将每组转换为MyPojo对象 .map(group -> { // 取组内第一个元素的公共字段值(name/desc/id相同) Schedule firstItem = group.get(0); // 收集组内所有type和freq List<String> types = group.stream().map(Schedule::getType).collect(Collectors.toList()); List<String> freqs = group.stream().map(Schedule::getFreq).collect(Collectors.toList()); return new MyPojo(firstItem.getId(), firstItem.getName(), firstItem.getDesc(), types, freqs); }) .collect(Collectors.toList()); // 打印验证结果 mergedResult.forEach(pojo -> { System.out.println(String.format( "{\"id\":\"%d\", \"name\":\"%s\", \"desc\":\"%s\", \"type\":%s, \"freq\":%s}", pojo.getId(), pojo.getName(), pojo.getDesc(), pojo.getType(), pojo.getFrequency() ).replace("[", "[\"").replace("]", "\"]").replace(", ", "\", \"")); }); } }
代码说明
- 分组逻辑:用
SimpleEntry<String, String>作为分组键,将name和desc的组合作为唯一标识,把同组合的Schedule分到一组; - 对象转换:对每个分组,取第一个元素的
id、name、desc作为公共值,再收集组内所有type和freq组成列表,最终实例化MyPojo; - 自定义分组键:如果不想用
SimpleEntry,也可以自定义一个包含name和desc的类,重写equals和hashCode方法作为分组键,效果一致。
内容的提问来源于stack exchange,提问作者vyas
相关产品推荐
相关产品推荐

