1、在Object類中的定義爲:
public native int hashCode();
是一個本地方法,返回的對象的地址值。
可是,一樣的思路,在String等封裝類中對此方法進行了重寫。方法調用獲得一個計算公式獲得的 int值。
2、在重寫任何類得hashcode方法時必須遵循如下幾點:
一、在Java應用的同一次執行過程當中,同一對象被屢次調用,則他們的hashcode值必然相同。
而對於同一個應用的兩次不一樣的調用,它們的Hashcode值能夠相同,也有可能不一樣。
二、對於兩個對象來講,若是他們的equals方法比較返回true,那麼這兩個對象的hashcode必然相同。
這也解釋了爲何String類中,若是兩個對象的equals方法相同,則他們的hashcode值必定相同。
三、對於兩個對象來講,若是使用equals方法返回爲false,則他們的hashcode的值有可能相等也可能不等,
(若是不一樣會提升性能,由於在集合中類判斷兩個對象是否相等,若是其hashcode不等就直接不用判斷equals方法了)
四、對於Object對象來講,不一樣的Object對象的hashcode是不一樣的,它們返回的是對象的地址,
equals返回的也是對象的地址。因此在本身定義的類中若是要添加到集合對象中,
最好是要重寫hashcode和equals方法,否則會自動繼承自Object類中的兩個方法根據對象地址來判斷。
在重寫本身定義的類時,一般是在類中的根據某個值如name.hashcode();來進行判斷。
3、以HashSet 爲例:
當咱們使用HashSet時,hashCode()方法就會被獲得調用,判斷已經存儲在集合中的對象的hashCode值是否與所增長。
對象的hashCode值一致,若是「不一致」則直接加進去(不用比較equals()提升效率),若是一致,則進行equals方法的比較,若是返回true,代表集合裏面已經有這個對象,不能添加進去了。若是是false表是集合裏面沒有這個對象,則能夠加進去。因此在重寫hashcode()或者equals() 方法的任何一個方法時,必須重寫另一個。
示例代碼:
/**
* People 手工重寫hashcode方法和equals方法 根據name來判斷 兩個對象是否相等。
*/
class People {
private String name;
public People(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
//若是是本身
if(this==obj){
return true ;
}
//若是是空
if(obj==null ){
return false;
}
//比較兩個People的名字是否相同
if(obj!=null && obj instanceof People){
if(((People)obj).name.equals(this.name))
return true ;
}
return false;
}
@Override
public int hashCode() {
// String的hashcode原本就是用來比較兩個字符是否相等
return name.hashCode();
}
}
最近看了Object類的源碼,對hashCode() 和equals()方法有了更深的認識。重寫equals()方法就必須重寫hashCode()方法的緣由,從源頭Object類講起就更好理解了。java
先來看Object關於hashCode()和equals()的源碼:程序員
光從代碼中咱們能夠知道,hashCode()方法是一個本地native方法,返回的是對象引用中存儲的對象的內存地址,而equals方法是利用==來比較的也是對象的內存地址。從上邊咱們能夠看出,hashCode方法和equals方法是一致的。還有最關鍵的一點,咱們來看Object類中關於hashCode()方法的註釋:
簡單的翻譯一下就是,hashCode方法通常的規定是:
再簡單的翻譯一下第二三點就是:hashCode()和equals()保持一致,若是equals方法返回true,那麼兩個對象的hasCode()返回值必須同樣。若是equals方法返回false,hashcode能夠不同,可是這樣不利於哈希表的性能,通常咱們也不要這樣作。重寫equals()方法就必須重寫hashCode()方法的緣由也就顯而易見了。數組
假設兩個對象,重寫了其equals方法,其相等條件是屬性相等,就返回true。若是不重寫hashcode方法,其返回的依然是兩個對象的內存地址值,必然不相等。這就出現了equals方法相等,可是hashcode不相等的狀況。這不符合hashcode的規則。下邊,會介紹在集合框架中,這種狀況會致使的嚴重問題。app
class A {
String certificate;框架
public A(String certificate) {ide
this.certificate = certificate;
}性能
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (certificate == null) {
if (other.certificate != null)
return false;
} else if (!certificate.equals(other.certificate))
return false;
return true;
}ui
}this
class B {
String certificate;// 身份證號spa
public B(String certificate) {
this.certificate = certificate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
return result;
}
}
class C {
String certificate;
public C(String certificate) {
this.certificate = certificate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
C other = (C) obj;
if (certificate == null) {
if (other.certificate != null)
return false;
} else if (!certificate.equals(other.certificate))
return false;
return true;
}
}