第9條:覆蓋equals時老是覆蓋hashCode

在每一個覆蓋equals方法的類中,也必須覆蓋hashCode方法。不然,會違反Object.hashCode的通用約定,從而致使該類沒法結合全部基於散列的集合一塊兒正常工做,包括HashMap,HashSet,Hashtbale。ide

下面咱們先看下hashCode約定內容:性能

  1.只要對象equals方法的比較操做所用到的信息沒有被修改,對同一對象調用屢次,hashCode方法都必須返回同一整數。在同一應用程序的屢次執行過程當中,每次執行返回的整數能夠不一致。ui

  2.若是兩個對象根據equals(Object)方法比較是相等的,那麼這兩個對象的hashCode返回值相同。this

  3.若是兩個對象根據equals(Object)方法比較是不等的,那麼這兩個對象的hashCode返回值不必定不等,可是給不一樣的對象產生大相徑庭的整數結果,能提升散列表的性能。spa

若是不覆蓋hashCode方法,咱們在須要用到hashCode的地方可能不會如咱們所願,下面看個例子,有這麼一個類,咱們只覆蓋了equals方法,沒有覆蓋hashCode方法:.net

class MyObject{
    private String field01;

    public MyObject(String field01) {
        this.field01 = field01;
    }
    
    //覆蓋equals方法
    @Override
    public boolean equals(Object o) {    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass())
                return false;
        MyObject myObject = (MyObject) o;
        return (field01 == null ? myObject.field01 == null : field01.equals(myObject.field01));
    }
}

public class EffictiveTest {
    public static void main(String[] args) {
          Map<MyObject, String> map = new HashMap<>();
          map.put(new MyObject("123"), "123");
          System.out.println(map.get(new MyObject("123")));
    }
}

經過運行的結果咱們能夠看到key是new MyObject("123")時,value是null,從而咱們知道即便覆蓋了equals方法後仍是不能保證相等,緣由在於該類違反了hashCode的約定,因爲MyObject沒有覆蓋hashCode方法,致使兩個相等的實例擁有不相等的散列碼,put方法把此對象放在一個散列桶中,get方法從另一個散列桶中查找這個對象,這顯然是沒法找到的。code

  

當咱們加入hashCode方法後就正確顯示結果了。對象

//至於hashCode方法怎麼寫,返回的哈希值參考是什麼,能夠參考:http://blog.csdn.net/zuiwuyuan/article/details/40340355
@Override
public int hashCode() {
     int result = field01.hashCode() * 17;
     return result;
}

  

相關文章
相關標籤/搜索