=============================================html
原文連接: 爲何覆寫equals必需要覆寫hashCode? 轉載請註明出處!java
=============================================api
《Effective java》Chapter Three Item 9:Always override hashCode when you overried equals. (下載連接: Effective_java(英文版)第二版.pdf )oracle
一、 在Object中有兩個方法:app
public native int hashCode(); public boolean equals(Object obj) { return (this == obj);//默認比較引用相等 }
因此任何一個對象都有默認的hashCode()和equals()方法。ide
二、在hash表中,hashCode()方法是參與取/存值運算的。post
例如: ui
//HashTabel if ((e.hash == hash) && e.key.equals(key)) { return (V)e.value; } //HashMap if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e;
因而可知,在根據key取value的時候,key相等的必要條件就是二者hashCode相等。this
再說爲何覆寫equals必需要覆寫hashCode?注意:研究的對象是同一個類的兩個不一樣對象(引用不一樣)url
先看一段代碼:
@Test public void testHashCode(){ Student stu1 = new Student("JACK"); Student stu2 = new Student("JACK"); System.out.println(stu1.equals(stu2));//equal返回true System.out.println(stu1.hashCode()+"----"+stu2.hashCode());//hashCode 結果不一樣。因爲Student未覆寫hashCode方法,在計算的時候使用的是的Object.hashCode(),計算出來二者的hashCode不一致 HashMap map = new HashMap(); map.put(stu1,"123456"); System.out.println(map.get(stu2));//(邏輯上)本想取出「123456」,但hashMap在取值的時候把二者的hashCode加入比較,所以找不到相等的key值,因此取出結果爲null } class Student { private String name; public Student(String name){ this.name = name; } @Override public boolean equals(Object obj) { //邏輯上名字相等便認爲二者相等並非把引用相等做爲判等條件 return this.name.equals(((Student)obj).name); } }
運行結果以下:
true 668849042----434176574
null
由這段代碼能夠看出:在執行map.get(stu2)的時候,程序會獲取stu2的hashCode。而Student未覆寫hashCode(),因此直接使用父類Object.hashCode()計算hash值,而因爲Object.hashCode()返回的stu1和stu2的hash值並不相同,所以,map中未找到stu2對應的key值,因此返回的value便爲null。
而示例程序中,本想根據名字相等來判斷對象相等獲取value值「123456」,可因爲調用hashCode()的返回值不一樣致使最終未取得想要的值。那麼解決辦法是什麼?讓stu1.hashCode() == stu2.hashCode()。那麼該如何實現? 自定義(覆寫)hashCode()方法。
因此若是自定義了equals()方法,且返回true的充要條件不是(this == obj),那麼就必須覆寫hashCode,且必須保證equals爲true的時候二者的hashCode必須相等,不然當該對象做爲key值存在hash表中的時候,就沒法用邏輯上相等的對象取出該key所對應的value(如示例)。
Object specification [JavaSE6]: • Whenever it is invoked on the same object more than once during an execution of an application, the hashCode method must consistently return the same integer, provided no information
used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. • It is not required that if two objects are unequal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.
However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
----end