Hash碰撞问题
当两个对象的hashcode相同会发生什么?
HashMap底层是由数组以及键值对组成的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来确定存储位置的,HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突,解决hash冲突的方法有很多,HashMap底层是通过链表来解决hash冲突的。
image
HashMap储存数据示意图
如上图所示,哈希表是由数组+链表组成的,因为hashcode
相同,所以它们的bucket
位置相同,‘碰撞’会发生。因为HashMap
使用LinkedList
存储对象,这个Entry会存储在LinkedList
中,这个存储的位置一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。
如果两个键的hashcode相同,你如何获取值对象?
HashMap会使用键对象的hashcode
找到bucket位置,找到bucket
位置之后,会调用keys.equals()
方法去找到LinkedList中正确的节点,最终找到要找的值对象。从HashMap中get元素时,首先计算key的hashCode
,找到数组中对应位置的某一元素,然后通过key的equals
方法在对应位置的链表中找到需要的元素。