HashMap发生碰撞后怎么取碰撞的元素?

爱玩机的小毛毛


首先你得知道什么是hash碰撞!

当有数据存入哈希表时,先使用hash算法(其实就是一种压缩策略)计算数据的hash值,然后存入相应的数组中作为元素!因为是使用压缩,所以毫无疑问的会产生冲突,两个不同数据的hash值是一样的(比如hash算法是取模,101%10和91%10是一样的1作为hash值),这就是hash冲突,或者叫做hash碰撞!


解决hash碰撞主要有以下几种方式:

1,开放地址法:在发生hash碰撞的时候,采用一定的策略(比如线性查找该元素后面的空位放入,或者随机数探测方法等)将新的数据放入满足策略的空位置!

2,再哈希法:使用多种hash算法,当产生冲突的时候,使用下一种算法,直到找到空位插入为止,如果hash碰撞比较严重,使用这种方法会大大增加hash计算时间!

3,链地址法:把每个数组的元素看做链表,变为数组+链表的数据形式,在发生冲突的时候,把新数据插入到对应元素的链表中!

举个例子,比方说一个250000的数据,如果使用寻常的方式顺序查找,需要125000次比较,而如果使用hash表(假设是十分均匀的hash表,数组是500个元素,链表是500个节点),则只需要500/2+500/2=500次比较,就可以查到!效率从O(N)降到了O(1)常量级别!


很多语言中都有hash的实现,而在JDK中使用的就是链地址法来解决哈希冲突的,不过在j d k8中,当链表节点数大于8的时候,会自动转换成红黑树,进一步提升了查询的效率!

hashmap是面试中常常提及的点,需要重点关注下,一直走在JAVA开发技术分享的道路上,从不停歇,敬请关注!!


此生唯一


首先,要知道HashMap的实现,HashMap是采用数组+链表的数据结构,数组是用做于散列的桶,由于无法确保散列值唯一,也就是问题中的冲突碰撞,这时冲突碰撞就由链表结构来解决。


再讲链表是如何解决冲突碰撞,当出现哈希值相同时,就把冲突的元素也就是键值对添加进哈希值对应桶的链表中,查询元素时通过遍历链表来实现。

但是当桶数目较小,散列后冲突碰撞产生太多就会造成链表过长,从而大大降低了查询效率,所以在jdk1.8后为了解决这个问题,在判定链表过长就会从链表结构转换为红黑树结构(一种平衡二叉树结构),查询效率由O(n)变为log(n),大大提高。


以上便是本学生对hashmap的理解和了解,希望能帮助到你,如果有错误请指出互相学习。


分享到:


相關文章: