高级JAVA - 利用函数式接口实现通用的取并集/交集/差集

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 {

    /** 并集 - 新集合加旧集合的数据(去重) */
    private List unionList;

    /** 交集 - 新集合和旧集合都有的数据 */
    private List intersectList;

    /** 主差集 - 新集合有 , 旧集合没有的数据 */
    private List exceptMainList;

    /** 次差价 - 旧集合有 , 新集合没有的数据 */
    private List exceptMinorList;

    private GatherData() {
        unionList = new ArrayList<>();
        intersectList = new ArrayList<>();
        exceptMainList = new ArrayList<>();
        exceptMinorList = new ArrayList<>();
    }

    private GatherData(List unionList, List intersectList, List exceptMainList, List exceptMinorList) {
        this.unionList = unionList;
        this.intersectList = intersectList;
        this.exceptMainList = exceptMainList;
        this.exceptMinorList = exceptMinorList;
    }

    /** 遍历并集操作 */
    public void unionEach(Consumer consumer) {
        forEach(this.unionList, consumer);
    }

    /** 遍历交集操作 */
    public void intersectEach(Consumer consumer) {
        forEach(this.intersectList, consumer);
    }

    /** 遍历主差集操作 */
    public void exceptMainEach(Consumer consumer) {
        forEach(this.exceptMainList, consumer);
    }

    /** 遍历次差集操作 */
    public void exceptMinorEach(Consumer consumer) {
        forEach(this.exceptMinorList, consumer);
    }

    /** @title 遍历集合并执行相关操作
     * @param consumer 函数式接口实现方法
     */
    private void forEach(List list, Consumer consumer) {
        for (T t : list) {
            consumer.accept(t);
        }
    }

    /**
     * @title 主要处理方法
     * @author Xingbz
     * @param newList 新数据集合
     * @param oldList 旧数据集合(一般为数据库记录)
     * @param function 业务转换方法(及两个集合中用来标识唯一的属性)
     */
    public static  GatherData handle(List newList, List oldList, Function function) {
        if (XDataUtil.isEmpty(newList) || XDataUtil.isEmpty(oldList)) {
            return new GatherData<>();
        }

        List newIdList = newList.stream().map(function).collect(Collectors.toList());//新ID集合
        List oldIdList = oldList.stream().map(function).collect(Collectors.toList());//旧ID集合

        //交集 : 新集合和旧集合都有的数据(此处返回的是旧集合 , 相当于数据库中的数据集合 , 是因为这部分数据还有创建时间更新时间等)
        List intersectList = oldList.stream().filter(ad -> newIdList.contains(function.apply(ad))).collect(Collectors.toList());

        //主差集 - 新集合有 , 旧集合没有的数据
        List exceptMainList = newList.stream().filter(ad -> !oldIdList.contains(function.apply(ad))).collect(Collectors.toList());

        //次差价 - 旧集合有 , 新集合没有的数据
        List exceptMinorList = oldList.stream().filter(ad -> !newIdList.contains(function.apply(ad))).collect(Collectors.toList());

        //并集 - 新集合加旧集合的数据(去重)
        List unionList = XDataUtil.addAllList(intersectList, exceptMainList, exceptMinorList);
        return new GatherData<>(unionList, intersectList, exceptMainList, exceptMinorList);
    }

    public static void main(String[] args) {
        List newList = new ArrayList<>();
        newList.add("3");
        newList.add("4");
        newList.add("5");
        List oldList = new ArrayList<>();
        oldList.add("1");
        oldList.add("2");
        oldList.add("3");
        oldList.add("4");

        GatherData gatherData = GatherData.handle(newList, oldList, Long::valueOf);
        List unionList = gatherData.getUnionList();
        List intersectList = gatherData.getIntersectList();
        List exceptMainList = gatherData.getExceptMainList();
        List exceptMinorList = gatherData.getExceptMinorList();
        System.out.println(unionList);
        System.out.println(intersectList);
        System.out.println(exceptMainList);
        System.out.println(exceptMinorList);
    }
}

实际项目中使用示例 : 

        //本次修改的所有用户
        List newList = dto.getUserList();
        //数据库中现有的所有对象
        List oldList = userMapper.selectDbUser(dto.getEmail());
        //取差集/交集 数据
        GatherData gatherUser = GatherData.handle(newList, oldList, User :: getUserId);
        //主差集(本次修改新增的) 保存
        gatherUser.exceptMainEach(userMapper::insert);
        //次差集(数据库原有但本次新增去掉的) 删除
        gatherUser.exceptMinorEach(userMapper::remove);

 

你可能感兴趣的:(Java,高级JAVA,源码)