爲何重寫了equals()就必需要重寫hashCode()

若是兩個對象的equals判斷爲true,那麼他倆的hashCode方法也必定相等。數組

重寫equals()就必需要重寫hashCode是針對HashSet 和Map 集合類型。結合框架只能存入對象(對象的引用(基本類型會自動裝箱))。框架

一、在向hashSet中存入元素時,hashSet會調用該對象的hashCode()方法來獲得該對象的hashCode()值,而後經過hashCode值決定該對象在hashSet中的存儲位置。也就是說hashSet集合判斷兩個對象相等的標準是:兩個對象經過equals()方法比較相等,而且對象的hashCode方法返回值也相等。若是兩個元素經過equals()方法返回true,可是他們的hashCode方法返回的值不一樣,hashSet也會把他們存儲在不一樣的位置,依然能夠添加成功。spa

在向集合中插入對象時,集合中有不少元素,若是用equals方法的話效率就是一個很大的問題了。這個時候就使用HashCode方法,當集合要添加新的元素時,先調用HashCode方法,實際上在HashMap的實現中會用一個table來保存對象的HashCode值,若是table中沒有這個值的話,就直接存進去,不用在進行任何比較了;若是存在該HashCode值,就調用他的equals方法與原先的元素進行比較,相同的話就替換原來的值,而且把原來的值返回,不相同就鏈表的形式往下存,這樣一來調用equals方法的評率就大大下降了。對象

二、在Map集合中,好比說hashMap 存儲的是<kety,value>對,key value都是對象,hashMap內部是經過key 對象的hashCode來計算桶的位置,這個桶裏面可能存在多個對象(Entry對象,包含key對象和value對象),所以會利用key對象和桶裏key對象調用equals逐一比較找到目標對象。當hashCode不一樣會放到兩個桶裏(當hashMap 內部數組不能在擴容時,有可能計算的hash值相等,也就是在相同的桶,可是這種狀況通常少見),所以當調用hashMap.get(key)時就不會找到你想要的目標對象。get

public class TestMap {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("1","11");
        map.put("2","23");
        System.out.println(map.entrySet().toString());
        for (Entry<String, String> entity :  map.entrySet()){
            String value =  entity.getValue();
            String key = entity.getKey();
            System.out.println(key + ":" + value);
        }

    }
}

結果是:hash

[1=11, 2=23]
1:11
2:23it

在hashMap中利用高16位 ‘與’ 低16位來計算key的hash值的這樣作主要是想散列的更散一些。儘可能讓每位都參與到運算中來。table

 

總結一下下:若是equals方法獲得的結果是false,則兩個對象的HashCode值必定不相等;class

若是兩個對象的HashCode值不相等,則equals方法獲得的結果一定爲false效率

若是兩個對象的HashCode值相等,則equals方法獲得的結果未知

相關文章
相關標籤/搜索