重写equals方法后,为何要重写hashCode方法?

版权声明:本文为博主原创文章,转载请说明出处 https://blog.csdn.net/u010002184/article/details/89298143

jdk1.8 Object类中hashCode方法的注释,翻译后如下:

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

注意第二条规定:当equals返回true时,保证hashCode返回的两个整数结果也相等!! 

实例1.1:不重写equals,也不重写hashCode

public class TestHashcode {

    private int i;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public static void main(String[] args) {
        TestHashcode a = new TestHashcode();
        TestHashcode b = new TestHashcode();
        a.setI(1);
        b.setI(1);
        Set<TestHashcode> codeSet = new HashSet<TestHashcode>();
        codeSet.add(a);
        codeSet.add(b);

        System.out.println(a.hashCode() + "," + b.hashCode());//调用Object.hashCode,哈希算法生成的
        System.out.println(a == b);//比较内存地址
        System.out.println(a.hashCode() == b.hashCode());//调用Object.hashCode,哈希算法生成的
        System.out.println(a.equals(b));//调用Object.equals,比较内存地址
        System.out.println(codeSet);
    }
}

2125039532,312714112
false
false
false
[testpackage.TestHashcode@12a3a380, testpackage.TestHashcode@7ea987ac]

实例1.2:重写equals,也不重写hashCode,添加代码:

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        TestHashcode thc = (TestHashcode) o;
        if (this.i == thc.i) {
            return true;
        }
        return false;
    }

修改输出代码的注释:

        System.out.println(a.hashCode() + "," + b.hashCode());//调用Object.hashCode,哈希算法生成的
        System.out.println(a == b);//比较内存地址
        System.out.println(a.hashCode() == b.hashCode());//调用Object.hashCode,哈希算法生成的
        System.out.println(a.equals(b));//调用TestHashcode.equals,比较属性i的值
        System.out.println(codeSet);

2125039532,312714112
false
false
true //此时equals返回true,但是hashCode不相等,违反规定2
[testpackage.TestHashcode@12a3a380, testpackage.TestHashcode@7ea987ac]

实例1.3:重写equals,也重写hashCode,添加代码:

    @Override
    public int hashCode() {
        return i % 10;
    }

修改输出代码的注释:

        System.out.println(a.hashCode() + "," + b.hashCode());//调用TestHashcode.hashCode,哈希算法生成的
        System.out.println(a == b);//比较内存地址,
        System.out.println(a.hashCode() == b.hashCode());//调用TestHashcode.hashCode,哈希算法生成的
        System.out.println(a.equals(b));//调用TestHashcode.equals,比较属性i的值
        System.out.println(codeSet);

1,1
false
true
true
[testpackage.TestHashcode@1]

为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,

以上基于jdk1.8

猜你喜欢

转载自blog.csdn.net/u010002184/article/details/89298143