美文网首页Java二三事
两个对象List根据属性取交集和差集

两个对象List根据属性取交集和差集

作者: 码哥说 | 来源:发表于2020-05-16 10:20 被阅读0次

    背景介绍

    咸鱼君最近做了个需求, excel导入功能,

    其中

    需要对已导入条目的做“更新”

    未导入的条目做“新增”

    其余的做“删除”

    细品需求

    无非是对excel的数据和数据库的数组做个差集, 交集的处理

    打个比方:

    excel的数据我们定义为 newList

    已导入的数据我们定义为 existList

    那么

    • newList 和 existList 的交集 就是 更新的数据

    • newList - existList 的差集 就是 新增的数据

    • existList - newList 的差集 就是 删除的数据

    不难看出, 这边就需要两个方法

    一个是求交集

    另一个就是求差集

    此时, 很多人for, foreach的思维开始了…………

    收起你过时的想法!

    jdk8都更新了stream流操作和lamba表达式,你居然还想要for这种操作?!

    你难道自信自己写的方法比stream高效安全?!

    下面, 我们就介绍下stream()和lamba表达式结合来处理差集交集的操作

    定义Excel实体

    excel中每行记录都是人的数据, 所以我们定义一个实体

    class People{
        //姓名
        private name;
        //身份证
        private code;
    }
    

    业务比对

    我们定义了People实体可以看出身份证是唯一的所以我们比对数据时可以用code这个属性来比较那么对应的业务需求可以描述成这样

    List<People> existPeopleList = 查询数据库;
    List<People> newPeopleList  = excel读取的新数据
    //需要更新的数据,参数顺序注意
    List<People> updateProple = sameList(existPeopleList, newPeopleList); 
    //需要删除的数据
    List<People> delList = diffList(existPeopleList, newPeopleList); 
    //需要新增的数据
    List<People> inserList = diffList(newPeopleList, existPeopleList);
    

    这边注意

    sameList(existPeopleList,newPeopleList))参数的顺序很重要

    打个比方:

    existPeopleList中有个 code 为1 的 name 为1;

    newPeopleList中有个 code 为1 的 name 为11;

    传参顺序将决定返回的是1还是11!

    这里具体看大家的业务是什么!(事实上,更新肯定是以excel的数据为准)

    下面我们正式介绍sameList()和diffList()的实现

    求两个对象List的交集

    private List<People> sameList(List<People> oldArrayList, List<People> newArrayList) {
            List<People> resultList = newArrayList.stream()
                    .filter(item -> oldArrayList.stream().map(e -> e.getCode())
                            .collect(Collectors.toList()).contains(item.getCode()))
                    .collect(Collectors.toList());
            return resultList;
        }
    

    求两个对象List的差集

    private List<People> diffList(List<People> firstArrayList, List<People> secondArrayList) {
            List<People> resultList = firstArrayList.stream()
                    .filter(item -> !secondArrayList.stream().map(e -> e.getCode()).collect(Collectors.toList()).contains(item.getCode()))
                    .collect(Collectors.toList());
            return resultList;
    ​    }
    

    求两个对象List的差集(多属性比对)

    比对的时候我们需要的可能不止一个参数

    所以,咸鱼君列出一个通用的多属性比对求差集的方法

    比如我们需要code和name两个属性才能比对则

    e -> e.getCode() + "&" + e.getName()
    

    再比如还需要个加age属性

    e -> e.getCode() + "&" + e.getName()+ "&" +e.getAge();
    

    依此类推

    private List<People> diffList(List<People> firstArrayList, List<People> secondArrayList) {
            List<People> resultList = firstArrayList.stream()
                    .filter(item -> !secondArrayList.stream().map(e -> e.getCode() + "&" + e.getName())
                            .collect(Collectors.toList()).contains(item.getCode() + "&" + item.getName())
                    )
                    .collect(Collectors.toList());
            return resultList;
        }
    

    最后

    Stream()结合Lamba表达式可以做很多事

    数据过滤, 筛选, 分组, 聚合等等

    大家可以多多学习~

    欢迎关注我

    相关文章

      网友评论

        本文标题:两个对象List根据属性取交集和差集

        本文链接:https://www.haomeiwen.com/subject/zcclohtx.html