hashMap工作原理和hash碰撞


這一章節我們來討論一下hash碰撞。

1.什么是hash碰撞?

就是兩個對象的key的hashcode是一樣的,這個時候怎么get他的value呢?

答案是通過equals遍歷table那個位置上面的Entry鏈表。


2.例子

正常的例子:

[java]  view plain  copy
 
  1. package import publicclass publicstaticvoid new new );  
  2. );  
  3. );  
  4. new );  
  5. );  
  6. );  
  7. new );  
  8. );  
  9. new );  
  10. );  
  11.  + map.get(person_1).getName());  
  12.  + map.get(person_2).getName());  
  13. class privateint;  
  14. private;  
  15. publicint return publicvoidint this public return publicvoid this   
  16. publicint return   
  17. publicboolean returnsuper class privateint;  
  18. private;  
  19. privateint;  
  20.   
  21. publicint  + thisthis returnsuper publicint return publicvoidint this public return publicvoid this publicint return publicvoidint this   
  22. public return + id + thisthis   
  23. publicboolean  + id +  returnsuper }  


輸出:

person id:1,hashCode() invoked,hashcode:443164103180
person id:2,hashCode() invoked,hashcode:443164103180
person id:1,hashCode() invoked,hashcode:443164103180
--dog_1
person id:2,hashCode() invoked,hashcode:443164103180
--dog_2


解釋:

(1)上面建立兩個類,然后分別在hashCode和equal方法里面加上輸出語句

(2)通過輸出可以看到,其實我們重寫的equals方法是沒有被調用的,我們只需要通過hashcode就可以定位相應的對象


hash碰撞的代碼:

[java]  view plain  copy
 
  1. package import publicclass publicstaticvoid new new );  
  2. );  
  3. );  
  4. new );  
  5. );  
  6. );  
  7. new );  
  8. );  
  9. new );  
  10. );  
  11.  + map.get(person_1).getName());  
  12.  + map.get(person_2).getName());  
  13. class privateint;  
  14. private;  
  15. publicint return publicvoidint this public return publicvoid this   
  16. publicint return   
  17. publicboolean returnsuper class privateint;  
  18. private;  
  19. privateint;  
  20.   
  21. publicint  + thisthis returnthisthis  
  22. publicint return publicvoidint this public return publicvoid this publicint return publicvoidint this   
  23. public return + id + thisthis   
  24. publicboolean  + id +  returnsuper }  

輸出:
[java]  view plain  copy
 
  1. person id:,hashCode() invoked,hashcode:  
  2. ,hashCode() invoked,hashcode:  
  3. 2 ,hashCode() invoked,hashcode:  
  4. 1 ,hashCode() invoked,hashcode:  
  5. --dog_2  

解釋:

(1)我們重寫了Person,也就是key的hashCode方法,人為的產生hash碰撞現象

(2)從輸出可以看出,上面的代碼需要用到equals方法


回歸put和get的源碼;

下面是put的源碼:

[java]  view plain  copy
 
  1. public ifnull return int int fornull if  
  2. this return returnnull    }  

下面是get的源碼:


[java]  view plain  copy
 
  1. public ifnull return int for null if  
  2. return returnnull     }  

大家請注意我上面注釋“注意的地方”:

(1)如果是平常沒有hash碰撞的時候,前面的兩個hash比較再加上key的地址的比較即可,然后后出現“短路”現象,使得后的句子不再執行。

(2)但是在出現hash碰撞的情況下,前面兩個條件都成立,然后必須使用最后的equals來判斷對象的相等。


3.hash碰撞出現的情景?

(1)一般會出現在大的數據情況之下

(2)hashcode的生成方法唯一性較弱(比如上面的人為的生產hashcode)


總結:這一章節主要通過介紹hash碰撞再一次深入了解HashMap的工作原理。


這一章節就到這里,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM