码迷,mamicode.com
首页 > 其他好文 > 详细

List的remove方法里的坑

时间:2019-05-18 23:54:18      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:print   fas   return   生成   upd   自定义   调用   color   market   

  今天遇到一件怪事,用一个ArrayList添加了一个对象,再调用ArrayList的remove方法删除该对象,当然这时对象是数据库里查出来的,但内容绝对是一样,却发现remove失败了。演示一下,这里用了自定义的Merchant对象,测试时只需随便自定义一个对象即可:

  

  public static void main(String[] args) {
        List<Merchant> merchants = new ArrayList<>();
        Merchant merchant = new Merchant();
        merchant.setMerchantId("aa");
        merchant.setMarketPlaceId("bb");
        merchant.setSecretKey("aa");
        merchant.setAccessKeyId("bb");
        merchants.add(merchant);
        Merchant other = new Merchant();
        other.setMerchantId("aa");
        other.setMarketPlaceId("bb");
        other.setSecretKey("aa");
        other.setAccessKeyId("bb");

        boolean isRemoved = merchants.remove(other);

        System.out.println(isRemoved);
    }

  结果打印出来是false。然后去看了一下ArrayList的remove方法:

    public boolean remove(Object var1) {
        int var2;
        if (var1 == null) {
            for(var2 = 0; var2 < this.size; ++var2) {
                if (this.elementData[var2] == null) {
                    this.fastRemove(var2);
                    return true;
                }
            }
        } else {
            for(var2 = 0; var2 < this.size; ++var2) {
                if (var1.equals(this.elementData[var2])) {
                    this.fastRemove(var2);
                    return true;
                }
            }
        }

        return false;
    }

    private void fastRemove(int var1) {
        ++this.modCount;
        int var2 = this.size - var1 - 1;
        if (var2 > 0) {
            System.arraycopy(this.elementData, var1 + 1, this.elementData, var1, var2);
        }

        this.elementData[--this.size] = null;
    }

   关键在标黄那一行,remove的前提是两个对象的equals方法必须相等,而我定义的Merchant对象并无复写Object类的equals方法,那么执行到这一行时equals就是Object的equals方法:

    public boolean equals(Object obj) {
        return (this == obj);
    }

  是否一下子有种恍然大悟的被坑的感觉?反正我是这样子觉得的,Object类比较的是引用,而main里测试的是两个不同的引用,equals必然是false,remove自然也是false了,不信可以把equals也一并打印一下:

    public static void main(String[] args) {
        List<Merchant> merchants = new ArrayList<>();
        Merchant merchant = new Merchant();
        merchant.setMerchantId("aa");
        merchant.setMarketPlaceId("bb");
        merchant.setSecretKey("aa");
        merchant.setAccessKeyId("bb");
        merchants.add(merchant);
        Merchant other = new Merchant();
        other.setMerchantId("aa");
        other.setMarketPlaceId("bb");
        other.setSecretKey("aa");
        other.setAccessKeyId("bb");

        boolean isRemoved = merchants.remove(other);

        System.out.println(other.equals(merchant));
        System.out.println(isRemoved);
    }

  你会发现两个false出现了。那么咋办呢?很简单,既然是equals引起的,那就让它来解决问题,我们再Merchant里重写Object的equals即可。当然既然重写了equals,我们也得把hashCode方法也一起重写一下,现在的IDE都很智能,自动生成即可。等你的自定义类生成好了这俩方法后,重新执行上面这个main,你会发现出现俩true了。

  当然,如果你希望在自定义的对象里修改了非关键属性(比如上面的Merchant里的accessKeyId、secretKey等这些属性,在数据库update他们的值之后就都改变了)都不影响该对象的唯一性,那么我们可以把equals和hashCode方法里自动生成的其他属性去掉,只保留能识别该对象的关键属性(比如merchantId)。

List的remove方法里的坑

标签:print   fas   return   生成   upd   自定义   调用   color   market   

原文地址:https://www.cnblogs.com/wuxun1997/p/10887511.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!