为什么重写equals方法还需要重写hashCode方法

为什么重写equals方法还需要重写hashCode方法

每个类都有一个equals方法和hashcode方法。因为所有的类都继承自Object类。
Object类中定义如下:
public class Object {

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

equals方法默认比较的是对象的引用,直接用“==”进行比较。
而hashCode方法是一个native方法,返回值为整型;
这两个方法都未被final修饰,都是可以进行重写的
经常使用的比如String 、Math、Integer、Double等类,都进行了equals()和hashCode()方法的重写

equals()方法是用来判断两个对象是否相等。Object默认实现了equals方法,但很明显不太符合个性化的需求,
因此往往需要进行重写。比如常用的String类,重写的equals方法如下:

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;
}
首先通过内存地址进行比较,如果内存地址相同那么肯定是相同的对象。
如果内存地址不同就再拿char数组的内容进行比较,完全相等则返回true

public class Test01 {

    public static void main(String[] args) {
        String ff = new String("abcdef");
        String dd =new String("abcdef") ;
        String ee = "abcdef";

        System.out.println("dd内存地址:" + dd.hashCode());
        System.out.println("ff内存地址:" + ff.hashCode());
        System.out.println("ee内存地址:" + ee.hashCode());
        System.out.println("dd内存地址:" + System.identityHashCode(dd));//内存地址
        System.out.println("ff内存地址:" + System.identityHashCode(ff));//内存地址
        System.out.println("ee内存地址:" + System.identityHashCode(ee));//内存地址


        System.out.println(dd == ff);// == 比较的是内存地址,
        System.out.println(dd.equals(ff)); // equals中,如果内存地址不一样,就比较值(内容)
        System.out.println(ee.equals(dd)); // equals中,如果内存地址不一样,就比较值(内容)

        System.out.println("比如上面的dd、ff、ee对象字符串内容相同,所以hashcode一定相同,因为hashcode是根据字符串内容来" +
                "计算的。但是内存地址就不一定相同了,equals方法先通过==比较内存地址,如果内存地址不一样,再比较字符串的值(内容)");

    }

}
输出结果:
dd的hashcode:-1424385949
ff的hashcode:-1424385949
ee的hashcode:-1424385949
dd内存地址:233530418
ff内存地址:683287027
ee内存地址:1766822961
false
true
true

结论:
上面的dd、ff、ee对象字符串内容相同,所以hashcode一定相同,因为hashcode是根据字符串内容来计算的。
但是内存地址就不一定相同了,equals方法先通过==比较内存地址,如果内存地址不一样,再比较字符串的值(内容)



复制代码

参考:重写equals方法时,为什么必须重写hashCode方法

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享