package com.xing.dto;
import com.xing.common.utils.XDataUtil;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @title 两个集合的聚合数据 , 包含并集/交集/差集
* @author Xingbz
* @createDate 2019-7-23
*/
@Data
public class GatherData<T> {
/** 并集 - 新集合加旧集合的数据(去重) */
private List<T> unionList;
/** 交集 - 新集合和旧集合都有的数据 */
private List<T> intersectList;
/** 主差集 - 新集合有 , 旧集合没有的数据 */
private List<T> exceptMainList;
/** 次差价 - 旧集合有 , 新集合没有的数据 */
private List<T> exceptMinorList;
private GatherData() {
unionList = new ArrayList<>();
intersectList = new ArrayList<>();
exceptMainList = new ArrayList<>();
exceptMinorList = new ArrayList<>();
}
private GatherData(List<T> unionList, List<T> intersectList, List<T> exceptMainList, List<T> exceptMinorList) {
this.unionList = unionList;
this.intersectList = intersectList;
this.exceptMainList = exceptMainList;
this.exceptMinorList = exceptMinorList;
}
/** 遍历并集操作 */
public void unionEach(Consumer<? super T> consumer) {
forEach(this.unionList, consumer);
}
/** 遍历交集操作 */
public void intersectEach(Consumer<? super T> consumer) {
forEach(this.intersectList, consumer);
}
/** 遍历主差集操作 */
public void exceptMainEach(Consumer<? super T> consumer) {
forEach(this.exceptMainList, consumer);
}
/** 遍历次差集操作 */
public void exceptMinorEach(Consumer<? super T> consumer) {
forEach(this.exceptMinorList, consumer);
}
/** @title 遍历集合并执行相关操作
* @param consumer 函数式接口实现方法
*/
private void forEach(List<T> list, Consumer<? super T> consumer) {
for (T t : list) {
consumer.accept(t);
}
}
/**
* @title 主要处理方法
* @author Xingbz
* @param newList 新数据集合
* @param oldList 旧数据集合(一般为数据库记录)
* @param function 业务转换方法(及两个集合中用来标识唯一的属性)
*/
public static <T, R> GatherData<T> handle(List<T> newList, List<T> oldList, Function<T, R> function) {
if (XDataUtil.isEmpty(newList) || XDataUtil.isEmpty(oldList)) {
return new GatherData<>();
}
List<R> newIdList = newList.stream().map(function).collect(Collectors.toList());//新ID集合
List<R> oldIdList = oldList.stream().map(function).collect(Collectors.toList());//旧ID集合
//交集 : 新集合和旧集合都有的数据(此处返回的是旧集合 , 相当于数据库中的数据集合 , 是因为这部分数据还有创建时间更新时间等)
List<T> intersectList = oldList.stream().filter(ad -> newIdList.contains(function.apply(ad))).collect(Collectors.toList());
//主差集 - 新集合有 , 旧集合没有的数据
List<T> exceptMainList = newList.stream().filter(ad -> !oldIdList.contains(function.apply(ad))).collect(Collectors.toList());
//次差价 - 旧集合有 , 新集合没有的数据
List<T> exceptMinorList = oldList.stream().filter(ad -> !newIdList.contains(function.apply(ad))).collect(Collectors.toList());
//并集 - 新集合加旧集合的数据(去重)
List<T> unionList = XDataUtil.addAllList(intersectList, exceptMainList, exceptMinorList);
return new GatherData<>(unionList, intersectList, exceptMainList, exceptMinorList);
}
public static void main(String[] args) {
List<String> newList = new ArrayList<>();
newList.add("3");
newList.add("4");
newList.add("5");
List<String> oldList = new ArrayList<>();
oldList.add("1");
oldList.add("2");
oldList.add("3");
oldList.add("4");
GatherData<String> gatherData = GatherData.handle(newList, oldList, Long::valueOf);
List<String> unionList = gatherData.getUnionList();
List<String> intersectList = gatherData.getIntersectList();
List<String> exceptMainList = gatherData.getExceptMainList();
List<String> exceptMinorList = gatherData.getExceptMinorList();
System.out.println(unionList);
System.out.println(intersectList);
System.out.println(exceptMainList);
System.out.println(exceptMinorList);
}
}
实际项目中使用示例 :
//本次修改的所有用户
List<User> newList = dto.getUserList();
//数据库中现有的所有对象
List<User> oldList = userMapper.selectDbUser(dto.getEmail());
//取差集/交集 数据
GatherData<User> gatherUser = GatherData.handle(newList, oldList, User :: getUserId);
//主差集(本次修改新增的) 保存
gatherUser.exceptMainEach(userMapper::insert);
//次差集(数据库原有但本次新增去掉的) 删除
gatherUser.exceptMinorEach(userMapper::remove);