如果重写 equals 方法,就必须也重写 hashCode 方法
两个对象的 hashCode 一致,那必然用equals方法判定的也是一致的。
equals()
在没有重写 equals() 方法的情况下,他与 == 一样是判断地址是否相同。
object 类的 equals() 的源码:
public boolean equals(Object obj) {
return (this == obj);
}
而 String 类自己重写了 equals 方法:
String 类中的 equals() 的源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
hashCode()
与 equals() 类似,在 object 类中一样有一个基础的定义,因此每个对象都有一个默认的散列码,其值为对象的存储地址。
object 类的 hashCode() 的源码:
@HotSpotIntrinsicCandidate
public native int hashCode();
这里只有一个 native 定义的本地方法并没有方法体,也就是说是由 c++或 c 写的方法来获取存储地址。
而在 String 类中,重写了 hashCode 方法,他的值是根据内容算出来的,并不是地址,所以说我们不能认为 hashCode 就是地址值。
String 类的 hashCode() 的源码:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
例子:
public static void main(String[] args) {
String s = "OK";
String t = new String("OK");
System.out.println(s.equals(t));
}
输出结果为:
true
由源码可知,他们的值一样,所以hashCode一样,则equals返回为真。
toString()
无限推荐为自己定义的每一个类添加toString 方法,这是一个良好的编程习惯!
object 类的 toString() 的源码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}