com.github.hetianyi.common.util.DiffUtil Maven / Gradle / Ivy
package com.github.hetianyi.common.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 集合diff操作
*
* @author Jason He
* @version 1.0.0
* @since 1.0.0
* @date 2019-12-27
*/
public class DiffUtil {
/**
* 根据常见业务场景提取的diff操作,
* 将两个不同的全量集合进行diff操作,挑选出新增,更新和删除集合
*
* @param oldList 旧集合数据
* @param newList 新集合数据
* @param comparator 比较器,判断新旧集合中的两个元素是否属于同一元素。
* 例如,根据元素的主键id判断两个元素是同一元素。
* @param
* @return
*/
public static DiffTuple diff(List oldList, List newList,
Comparator comparator) {
// 如果oldList为空,则所有元素是新增的,没有删除和更新的
if (CollectionUtil.isNullOrEmpty(oldList)) {
return new DiffTuple(newList, null, null);
}
// 如果newList为空,则所有元素是删除的,没有新增和更新元素
if (CollectionUtil.isNullOrEmpty(newList)) {
return new DiffTuple(null, null, oldList);
}
AssertUtil.notNull(comparator, "comparator cannot be null");
List updates = new ArrayList<>(oldList.size());
// 方便快速查询
Set updateSet = new HashSet<>(oldList.size());
List deletes = new ArrayList<>(oldList.size());
List news = new ArrayList<>(oldList.size());
// 获取更新元素
oldList.forEach(v ->
newList.forEach(k -> {
if (comparator.isSame(v, k)) {
updates.add(k);
updateSet.add(v);
updateSet.add(k);
}
})
);
// 过滤删除元素
oldList.forEach(v -> {
if (!updateSet.contains(v)) {
deletes.add(v);
}
});
// 过滤新增元素
newList.forEach(v -> {
if (!updateSet.contains(v)) {
news.add(v);
}
});
return new DiffTuple(news, updates, deletes);
}
/**
* 获取集合src不在集合target中的元素。
*
* @param src 源集合
* @param target 目标集合(被比较对象)
* @param comparator 比较器,判断新旧集合中的两个元素是否属于同一元素。
* 例如,根据元素的主键id判断两个元素是同一元素。
* @param
* @return
*/
public static List notIn(List src, List target,
Comparator comparator) {
if (CollectionUtil.isNullOrEmpty(target)) {
return src;
}
if (CollectionUtil.isNullOrEmpty(src)) {
return null;
}
AssertUtil.notNull(comparator, "comparator cannot be null");
Set sameSet = new HashSet<>(src.size());
src.forEach(v -> target.forEach(k -> {
if (comparator.isSame(v, k)) {
sameSet.add(v);
}
}));
List result = new ArrayList<>(src.size());
src.forEach(v -> {
if (!sameSet.contains(v)) {
result.add(v);
}
});
return result;
}
/**
* 获取集合src和集合target交集。
*
* @param src 源集合
* @param target 目标集合(被比较对象)
* @param comparator 比较器,判断新旧集合中的两个元素是否属于同一元素。
* 例如,根据元素的主键id判断两个元素是同一元素。
* @param
* @return
*/
public static List share(List src, List target,
Comparator comparator) {
if (CollectionUtil.isNullOrEmpty(target) || CollectionUtil.isNullOrEmpty(src)) {
return null;
}
AssertUtil.notNull(comparator, "comparator cannot be null");
List result = new ArrayList<>(src.size());
src.forEach(v -> target.forEach(k -> {
if (comparator.isSame(v, k)) {
result.add(v);
}
}));
return result;
}
public static class DiffTuple {
private List addedList;
private List updatedList;
private List deletedList;
public DiffTuple() {
}
public DiffTuple(List addedList, List updatedList, List deletedList) {
this.addedList = addedList;
this.updatedList = updatedList;
this.deletedList = deletedList;
}
public List getAddedList() {
return addedList;
}
public void setAddedList(List addedList) {
this.addedList = addedList;
}
public List getUpdatedList() {
return updatedList;
}
public void setUpdatedList(List updatedList) {
this.updatedList = updatedList;
}
public List getDeletedList() {
return deletedList;
}
public void setDeletedList(List deletedList) {
this.deletedList = deletedList;
}
}
/**
* 比较两个集合元素是否相同
* @param
*/
public interface Comparator {
boolean isSame(T t1, T t2);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy