List.removeAll()无效 解决方案

  • Post author:
  • Post category:其他




List.removeAll()无效解决方案



问题:

使用List.removeAll()方法去求 List list1 和 List list2 的差集时,会发现 list1.removeAll(list2)无效,list1的size并没有发生变化。



原因:

执行 removeAll() 方法流程如下图所示:

在这里插入图片描述

分析发现 自定义对象的equals()方法使用的是 Object的equals()方法,比较的是对象在JVM中的内存地址,而不是像String类一样只是比较值的相同(String类覆盖了equals()方法)。


String.equlas() :

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }


Object.equals():

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

那思路就很清晰了,我们只需要重写我们自定义对象的 equals()方法就可以解决该问题了,但是在equals()方法上有一大段注释就是在说明该方法遵循的规范,借鉴一下大佬翻译好的:


equals 方法实现的时候必须要满足的特性:

1.(reflexive)自反性:

对于任何非 null 的引用值 x,x.equals(x) 必须为 true;

2.(symmetric)对称性:

对于任何非 null 的引用值 x,y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 也要返回 true 。

3.(transitive)传递性:

对于任何非 null 的引用值 x,y,z, 如果 x.equals(y) 返回 true,y.equals(z) 返回 true,那么 x.equals(z) 一定要返回 true。

4.(consistent)一致性:

对于任何非 null 的引用值 x,y,只要 equals() 方法没有修改的前提下,多次调用 x.equals(y) 的返回结果一定是相同的。

5.(non-nullity)非空性

对于任何非 null 的引用值 x,x.equals(null) 必须返回 false。

由于

quals 方法实现的时候必须要满足的特性

需要去检查自己写的方法是否符合规范,很浪费时间,不仅如此,

覆盖 equals 时,一定要同时覆盖 hashCode()方法

这样做的目的是保证每一个 equals()返回 true 的两个对像,要有两个相同的 hashCode 。



解决方案:

使用Lombok 中 包含的注解 @EqualsAndHashCode来自动覆盖equals()和hashCode()方法。

在 IDEA > Setting > Plugins 中搜索 lombok 下载支持插件

在这里插入图片描述

使用Maven引入

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-maven</artifactId>
    <version>1.16.20.0</version>
</dependency>

之后在需要覆盖重写equals()和hashCode()方法的类里 使用 @EqualsAndHashCode注解 就大功告成了


参考:



一个由List.removeAll()失效引发的思考



版权声明:本文为yaheng100原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。