半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法

Posted 码上猿梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法相关的知识,希望对你有一定的参考价值。

我说的半夜, 并不是真正的半夜, 指的是在我一个人的时候, 我会去思考一些奇怪的问题.

这次思考的如题所示, 为什么重写 equals() 方法时, 强烈建议重写 hashCode() 方法, 这个答案, 应该大多数人都知道, 是为了减少 equals() 方法的调用, 只有当两个对象的 hashCode 相等时, 才会去调用 equals()方法去判断两个对象是否相等, 减少了equals()的调用, 提高了效率 .

 

话是这么说,  的确, 可以减少很多次的 equals()方法的调用, 但是不也是调用了 hashCode() 方法吗? 怎么就提高了效率了呢 ?

      先说下什么情况下会重写 equals()方法, 一般情况, 实体类都需要根据自身的字段来实现 equals()方法, 在学习集合的时候, 一个是 Set 集合, 一个是 Map集合, 我对这两个集合的理解就是, 他俩是同母异父, 来的根源是一样的, 只是表现的不一样, 在存储自定义的实体类时, 为了保证存储的实体类不重复, 这也是 Set, Map的特性了, 比如需要存储两个人, 谁能证明两个人不同呢?  有两种方式证明 : 第一种是他们自己就具备证明的方法 ( 也就是Person类实现了Comparable接口 ),

第二种方式 : 派出所的人现场开证明 ( 传入比较器对象 ) , 好像扯远了, 和标题不一致了 .

     我的记忆有点混乱了, 以为 compareTo() 方法需要使用到 equals()方法, 看了源码, 原来不需要, 罪过罪过,

源码放上来, 以防以后忘记 :

/*
字符串的比较的方法, 将字符串转换为char数组,
以为char是基本类型, 可以使用等号进行判断
*/
public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

回忆一下, 原来是集合的 contains()方法依赖 equals()方法,

 

 

调用方法的数量是一致的, 效率的提高, 那么效率就在方法中了, 我直接拿 String类的源码来解释,

以上是关于半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法的主要内容,如果未能解决你的问题,请参考以下文章

重写 Equals 方法时是不是需要重写 == 和 != 运算符? (。网)

java中重写Object类的equals方法为啥要重写hashcode方法?不重写可以吗?

总结,为什么要重写hashset的hashcode()和equals()?

java中为什么重写equals时必须重写hashCode方法?

为什么重写equals时必须重写hashCode方法?(转发+整理)

重写java equals 方法的建议