image.png
需求:用户会上送一个新集合,需要和DB中旧集合比较。
新集合有,旧集合没有的数据会保存。
新集合有,旧集合有的数据会更新。
新集合没有,旧集合有的数据会删除。
上述需求可以转换为两个集合取 差集/交集。
JDK为我们提供了对应的API方法:
public static void main(String[] args) {
List newList = new ArrayList<>();
newList.add("A");
newList.add("B");
newList.add("C");
newList.add("D");
List oldList = new ArrayList<>();
oldList.add("C");
oldList.add("D");
oldList.add("E");
oldList.add("F");
}
求差集:
//最终得到的数据是C,D(需要插入的数据)
newList.removeAll(oldList);
System.out.println(JSON.toJSONString(newList));
//最终得到的数据是E,F(需要删除的数据)
oldList.removeAll(newList);
System.out.println(JSON.toJSONString(oldList));
求并集:
//最终得到的数据是C,D(需要更新的数据)
oldList.retainAll(newList);
System.out.println(JSON.toJSONString(oldList));
但是在实际开发中,JDK提供的方法并不能完全的满足业务需要。
业务场景需求:
上送的新集合,新集合中的元素主键id必须为空才会去保存。
新集合和旧集合只要主键id相同,那么就是一条记录,就需要去更新(若是使用ArrayList求并集的方法,那么必须重写equals方法,只要id相同那么就是true)。
获取差集/并集后不能去修改原集合。
//集合关系的包装类
@Data
public class ListRelationshipWrapper {
//需要插入的数据
private List insertInfos;
//需要更新的数据
private List updateInfos;
//需要删除的数据
private List deleteInfos;
}
public abstract class AbstractListRelationship {
//获取到实体的主键
protected abstract ID renderKey();
//根据id判断是否能插入
protected abstract boolean checkIdSave();
//判断实体是否相等
protected abstract boolean renderEquals(T data);
//获取集合的关系
public static ListRelationshipWrapper getListRelationship(List extends AbstractListRelationship> oldData,
List extends AbstractListRelationship> newData){
ListRelationshipWrapper wrapper = new ListRelationshipWrapper<>();
List insertInfos =new ArrayList();
Map newDataMap = new HashMap<>();
//新集合(1,3)
for(AbstractBeanDifference data : newData){
Object o = data.renderKey();
if(data.checkIdSave()){
//若是能插入,保存到insertDatas集合中。
insertDatas.add(data);
}else{
//以id为key,保存对象
newDataMap.put(o,data);
}
}
wrapper.setInsertDatas(insertDatas);
List deleteDatas = new ArrayList();
List updateDatas = new ArrayList();
//旧集合
for(AbstractBeanDifference data : oldData){
//包含id,则更新
if (newDataMap.containsKey(oldData)) {
//两个对象不相等,才去更新
if (!data.renderEquals(newDataMap.get(oldData)))
updateDatas.add(newDataMap.get(oldData));
} else {
deleteDatas.add(newDataMap.get(oldData));
}
}
wrapper.setDeleteDatas(deleteDatas);
wrapper.setUpdateDatas(updateDatas);
return differenceWrapper;
}
}
推荐阅读