冰凍非一日之寒
java中儒旬,對于任何類型的數(shù)據(jù)調(diào)用hashCode方法都會返回一個哈希值,并且這個哈希值是個整型帖族。
需要注意的是栈源,基本數(shù)據(jù)類型需要轉(zhuǎn)化為相應(yīng)的封裝類才能調(diào)用hashCode方法。因為對象才有方法竖般,而基本數(shù)據(jù)類型是沒有方法的甚垦。
基本類型對應(yīng)的封裝類如下圖
java默認(rèn)為每個類型返回一個哈希值,我們得到這個哈希值之后涣雕,再對這個哈希值取模求得索引艰亮,根據(jù)這個索引將數(shù)據(jù)存儲到數(shù)組(哈希表)中即可。
前面說過返回的哈希值是個整型挣郭,整型是可正可負(fù)的迄埃,什么時候會返回一個負(fù)的哈希值呢?或者這個整型是個什么樣的數(shù)呢丈屹?這與關(guān)鍵字有著直接聯(lián)系
當(dāng)關(guān)鍵字為小范圍整數(shù)時调俘,哈希值為關(guān)鍵字本身
當(dāng)關(guān)鍵字為浮點型數(shù)字時伶棒,哈希值為一個大整型
當(dāng)關(guān)鍵字為字符串時旺垒,哈希值是一個大整型
當(dāng)關(guān)鍵字為復(fù)合類時,哈希值也是一個大整型
hashCode方法只是將每個數(shù)據(jù)類型與一個整型對應(yīng)起來肤无,具體求相應(yīng)的索引時先蒋,需要在哈希表內(nèi)部結(jié)構(gòu)完成。
圖片
對于復(fù)合類來說宛渐,我們需要覆蓋Object父類中已有的hashCode方法竞漾,也就是重新計算哈希值。
圖片
這是為什么呢窥翩?
對于同一個類來說业岁,只要創(chuàng)建名字不同的對象,哈希值就會不同寇蚊,不管屬性值是否相同笔时。對于名字不同的對象,其哈希值是對象的存儲位置仗岸,在對象創(chuàng)建的同時就已經(jīng)確定了允耿。
所以會出現(xiàn)這種情況借笙,當(dāng)引用同一個復(fù)合類時,new兩個名字不同而屬性完全相同的對象時较锡,java默認(rèn)的hashCode方法返回的哈希值是不同的业稼,因為這個哈希值是在創(chuàng)建對象時就給定的,是對象的存儲位置蚂蕴。
但是低散,屬性值完全相同的兩個對象,顯然是同一個對象骡楼,哈希表中是不存儲兩個完全相同數(shù)據(jù)的谦纱,而它們的哈希值不同,取模后得到的索引也不同君编,這樣就會造成哈希表存儲了兩個相同數(shù)據(jù)跨嘉。
所以,我們要覆蓋掉復(fù)合類中自帶的hashCode方法吃嘿,引用同一個類時祠乃,對象的哈希值是確定的,并且一樣兑燥。那么問題又來了亮瓷,當(dāng)new兩個名字不同且屬性值不同的兩個對象時,他們的哈希值也相同~
這時降瞳,就需要再加判斷了嘱支。判斷兩個對象的屬性值是否相同,如果屬性值也相同挣饥,才是真正相同的兩個數(shù)據(jù)除师。
圖片
equals也是Object父類中自帶的方法,我們需要重寫這個方法扔枫,即判斷兩個對象屬性值是否相同汛聚。屬性值完全相同的兩個數(shù)據(jù),哈希表只會記錄下來一個短荐。
hashCode方法就介紹到這里了~