HashMap是如何解决哈希冲突的?
HashMap在jdk1.8版本中是通过链式寻址法,以及红黑树的方式来解决哈希冲突的。其中红黑树是为了优化Hash表的链表过长导致时间复杂度增加的问题。当链表长度大于8并且哈希表的大小大于64的时候,再向链表中添加元素,就会触发链表向红黑树的转化。
什么是哈希冲突?
由于哈希算法被计算的数据是无限的,而计算后的结果的范围是有限的,所以总会存在不同的数据,经过计算之后得到的值是一样的,这个情况下,就会产生哈希冲突。
通常解决Hash冲突的方法有哪些?
开放定址法(线性探测法)
从发生冲突的位置按照一定次序从Hash表中去找到一个空闲位置,然后把发生冲突的元素存入到这个位置,Java中ThreadLocal用到了线性探测法解决哈希冲突,当发生哈希冲突时向前去找一个空闲的位置,来存储这个冲突的key。
链式寻址法
把存在哈希冲突的key,以单向链表的方式来进行存储。HashMap就用到了链式寻址法来实现。存在冲突的key,直接以单向链表的方式进行存储。
再Hash法
把通过某个Hash函数计算得到的key存在冲突的时候,再用另外一个Hash函数对这个key进行哈希,一直运算,直到不再冲突为止。这种方式会增加计算的时间,性能上会有一些影响。
建立公共溢出区
把哈希表分为基本表和溢出表两个部分,存在哈希冲突的元素全部放入溢出表中。