两个对应不同类的list如果有相同的id,差集去重

今天上班,review同事写的代码,发现了一个bug,这里就不贴出实际代码了,自己写段代码,来重现一下这个bug。(别纠结代码,我是用groovy写的,有的人说你的java代码为什么没有分号,汗)。

其实,目的就是两个对应不同类但是有相同字段的list进行去重复的操作。

有两个类A,B

class A {

    Long id
    String detail

    Long getId() {
        return id
    }

    void setId(Long id) {
        this.id = id
    }

    String getDetail() {
        return detail
    }

    void setDetail(String detail) {
        this.detail = detail
    }
}
class B {

    Long id

    Long getId() {
        return id
    }

    void setId(Long id) {
        this.id = id
    }
}

这两个类有着相同的id字段。

现在假设的场景如下:

有三个用户A,内容分别是这样的

        A a1 = new A()
        a1.setId(1)
        a1.setDetail("a1detail")
        A a2 = new A()
        a2.setId(2)
        a2.setDetail("a2detail")
        A a3 = new A()
        a3.setId(3)
        a3.setDetail("a3detail")


有两个用户B,内容分别是这样的

        B b1 = new B()
        b1.setId(1)
        B b2 = new B()
        b2.setId(2)
        B b3 = new B()

分别存储到两个不同ArrayList<A> as 和 ArrayList<B> bs 中,最终想得到的内容是as中去掉id与bs中相同的用户,也就是上面情景中最终只剩下 a3用户。

这个同事写的代码是这样的:

        //new 两个新的list,将不同的结果存储到这两个list中
        ArrayList<A> returna = new ArrayList<>();
        ArrayList<B> returnb = new ArrayList<>();

        for (A a : aArrayList){
            for (B b : bArrayList){
                if (a.getId().equals(b.getId())){
                    returnb.add(b)
                    break
                }else {
                    returna.add(a)
                }
            }
        }

上面的代码中,else之后的语句是有问题,每次循环都有可能在遍历的时候,将之前存储过的对象a再次存储,从而出现重复。

正确的实现方式如下:

       for (B b: bArrayList){
            for (A a: aArrayList){
                if(b.getId().equals(a.getId())){
                    bReturn.add(b)
                    aArrayList.remove(a)
                    break
                }
            }
        }

因为bArrayList的集合是aArrayList集合的子集,所以最开始只是为了减少几次操作(不减少on方算法复杂度),才将bArrayList放在了最外层的循环中。

出于好奇,尝试把aArrayList放在外层循环,会发现报错的问题,报错如下:

Java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
        at java.util.HashMap$KeyIterator.next(HashMap.java:828)

后来发现,如果遍历ArrayList的时候,ArrayList增加或者删除了对象,就会报以上的错误,所以恰巧第一次写的代码正好在遍历aArrayList的时候,修改了aArrayList之后,break了当前的for循环。


报错参考下面的文章:

http://blog.csdn.net/lipei1220/article/details/9028669





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值