关于重写equals()和重写hashcode()

736 阅读2分钟

这是我参与更文挑战的第2天,活动详情查看:更文挑战

首先,equals()方法在object类中被定义时就是使用"=="方式来匹配的。也就是说,如果不重写equals()方法,并且对应的父类列表中都没有重写过,那么equals() 方法就是比较这两个 references 是否指向了同一个 object(我们常用的比较大小的符号之==,如果是基本数据类型,那么==就是比较数值的大小; 如果是引用类型,那么就比较的是这两个引用是否指向了同一个object)。

equals()方法之所以存在为了让你重写,是希望子类去实现对比值的功能,参考String:一般来说我们比较字符串就是想比较这两个字符串的内容的

str1 = “666;
str2 =  new String(“666”);

str1 == str2; // return false
str1.equals(str2); // return true 

因为String里是重写了equals()方法的:

/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    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;
    }

来看hashCode:这是一个native方法,返回的是对象的内存地址,它的约束条件如下

1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。 从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么两个对象不一定必须产生不同的整数结果。

但是,通常为不相等的对象生成不同整数结果可以提高哈希表的性能。实际情况是:hashcode返回的并不一定是对象的虚拟内存地址,具体取决于运行时库和JVM的具体实现。但对不同的object会返回唯一的哈希值。所以就有了hashCode()决定了key 放在这个桶里的编号,也就是在数组里的index;而equals()正是用来比较两个object是否相同的。

总结就是 两个对象相等,hashcode一定相等 两个对象不等,hashcode不一定不等 hashcode相等,两个对象不一定相等 hashcode不等,两个对象一定不等