diff算法
比较2个集合对象,得出哪些是新增的、哪些是删除的、哪些是更新的
public class DiffUtil {
@Data
@Accessors(chain = true)
public static class DiffResult {
/**
* 新增对象列表
*/
private List addedList;
/**
* 修改后的对象列表
*/
private List changedList;
/**
* 已删除对象列表
*/
private List deletedList;
}
/**
* 对比两个List的元素
*
* 如果 baseList 的元素在 targetList 中存在 PrimaryKey 相等的元素并且 elementComparator 比较结果不相等,则将修改后的值添加到changedList列表中;
* 如果 baseList 的元素在 targetList 中不存在,将baseList中的元素添加到deletedList中;
* 如果 targetList 的元素在 baseList 中不存在,将targetList中的元素添加到addedList中;
*
* complexity: O(n)
*
* @param baseList 基础List(原来的List)
* @param targetList 目标List(最新的List)
* @param elementComparator 元素比较器
* @param primaryKeyExtractor 主键选择器
* @param
* @return 对比结果
*/
public static DiffResult diffList(List baseList,
List targetList,
@NotNull Function primaryKeyExtractor,
@NotNull Comparator elementComparator) {
DiffResult checkResult = checkEmptyAndReturn(baseList, targetList);
if (checkResult != null) {
return checkResult;
}
Map baseMap = new HashMap<>(4096);
for(T base : baseList){
Object key = primaryKeyExtractor.apply(base);
baseMap.put(key,base);
}
List addedList = new ArrayList<>();
List changedList = new ArrayList<>();
List deletedList = new ArrayList<>();
//找出新增的 和需要更新的
for (T target : targetList) {
Object key = primaryKeyExtractor.apply(target);
T base = baseMap.get(key);
if(base == null){
addedList.add(target);
}else{
baseMap.remove(key);
if (elementComparator.compare(base, target) != 0) {
changedList.add(target);
}
}
}
//剩余的就是需要删除的
Set> entrySet = baseMap.entrySet();
if(CollectionUtils.isNotEmpty(entrySet)){
for(Entry entry:entrySet){
deletedList.add(entry.getValue());
}
}
return new DiffResult()
.setAddedList(addedList)
.setChangedList(changedList)
.setDeletedList(deletedList);
}
/**
* 检查baseList 和 targetList 为empty(null||size==0)的情况
*
* @param baseList
* @param targetList
* @param
* @return
*/
private static DiffResult checkEmptyAndReturn(List baseList, List targetList) {
if (CollectionUtils.isEmpty(baseList) && CollectionUtils.isEmpty(targetList)) {
return new DiffResult()
.setAddedList(null)
.setChangedList(null)
.setDeletedList(null);
}
if (CollectionUtils.isEmpty(baseList) && CollectionUtils.isNotEmpty(targetList)) {
return new DiffResult()
.setAddedList(targetList)
.setChangedList(null)
.setDeletedList(null);
}
if (CollectionUtils.isNotEmpty(baseList) && CollectionUtils.isEmpty(targetList)) {
return new DiffResult()
.setAddedList(null)
.setChangedList(null)
.setDeletedList(baseList);
}
return null;
}
@Data
@AllArgsConstructor
public static class User {
private Integer id;
private String userName;
private String realName;
}
}