天天看點

如果hashMap的key是一個自定義的類,怎麼辦?

hashcode()和equals()都繼承于object,在Object類中的定義為:

equals()方法在Object類中的定義:

public boolean equals(Object obj){

    return (this == obj);

}

equals()的定義為:

public native int hashCode();

是一個本地方法,傳回的對象的位址值。

     1.hashcode()和equals()是在哪裡被用到的?什麼用的?

     HashMap是基于散列函數,以數組和連結清單的方式實作的。

 而對于每一個對象,通過其hashCode()方法可為其生成一個整形值(散列碼),該整型值被處理後,将會作為數組下标,存放該對象所對應的Entry(存放該對象及其對應值)。

 equals()方法則是在HashMap中插入值或查詢時會使用到。當HashMap中插入 值或查詢值對應的散列碼與數組中的散列碼相等時,則會通過equals方法比較key值是否相等,是以想以自建對象作為HashMap的key,必須重寫 該對象繼承object的equals方法。

     2.本來不就有hashcode()和equals()了麼?幹嘛要重寫,直接用原來的不行麼?

    HashMap中,如果要比較key是否相等,要同時使用這兩個函數!因為自定義的類的hashcode()方法繼承于Object類,其hashcode碼為預設的記憶體地 址,這樣即便有相同含義的兩個對象,比較也是不相等的,例如,

Student st1 = new Student("wei","man");

Student st2 = new Student("wei","man"); 

正常了解這兩個對象再存入到hashMap中應該是相等的,但如果你不重寫 hashcode()方法的話,比較是其位址,不相等!

    HashMap中的比較key是這樣的,先求出key的hashcode(),比較其值是否相等,若相等再比較equals(),若相等則認為他們是相等 的。若equals()不相等則認為他們不相等。如果隻重寫hashcode()不重寫equals()方法,當比較equals()時隻是看他們是否為 同一對象(即進行記憶體位址的比較),是以必定要兩個方法一起重寫。HashMap用來判斷key是否相等的方法,其實是調用了HashSet判斷加入元素 是否相等。

另外,字元串為什麼使用魔數字 31,第一個他是一個不大不小的質數,int 溢出機率較小,且分布範圍較大,第二個是他在整個範圍内分布的機率均勻。