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