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

背景介绍

咸鱼君最近做了个需求, 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;
    }

补充(多属性异同比对)

举个列子, 两个属性比对,求出属性1相同,且属性2不同的交集
我们可以分步求解, 先找到属性1相同的,在此基础上找到属性2不同的即可.

灵活使用filter

    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()))
                .filter(item -> !secondArrayList.stream().map(e -> e.getName())
                        .collect(Collectors.toList()).contains(item.getName()))
                .collect(Collectors.toList());
        return resultList;
    }

最后

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

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

大家可以多多学习~

请关注我的订阅号

订阅号.png

  • 27
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值