为什么重写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方法先通过==比较内存地址,如果内存地址不一样,再比较字符串的值(内容)
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END