首页 > 编程知识 正文

哈希碰撞 解决方案,hash冲突和hash碰撞

时间:2023-05-05 07:37:25 阅读:9438 作者:4607

什么是Hash冲突? 对于混列冲突,必须提到混列映射的存储实现

如下图所示

也就是说,图中重复颜色的要素发生碰撞的就是Hash碰撞

计算得到的混列值相同,需要放入同一bucket时为混列冲突

解决Hash冲突(冲突)吗? java中使用的链接法、拉链法

jdk1.7中

调用HashMap的put或get方法时,首先调用hashcode方法以查找相关key,如果存在冲突,则调用equals方法

JDK1.7的时候使用Entry数组存储数据。 在key的hashcode中取模型,决定了key在数组中的位置。 如果hashcode相同,或者在hashcode中取模的结果相同,则这些key位于Entry数组的同一体量中。

jdk1.8中

只有在链表大于8、数组大于64时才进行转换,链表转换为红黑树,并调用treeifyBin函数

为什么8变成了红色的黑色的树? 根据概率学泊松分布

指示桶的链表元素超过8时,将自动转换为红黑树。 如果桶元素小于或等于6,则树结构将恢复为链表形式

中间有差7可以防止链表和树之间频繁切换

为什么不直接用红黑树? 因为红黑树需要左转、右转操作,不需要单链表。

主要考察链表与红黑树的比较:

1 )元素小于8个时,查询成本高,新增成本低

2 )元素大于8个时,查询成本低,追加成本高

1.7的put方法

publicvput(kkey,V V value ) if ) key==null ) returnputfornullkey ) value; inthash=hash(key.hashcode (); intI=indexfor(hash,table.length ); for(entryk,V e=table[i]; e!=null; e=e.next({objectk; if(e.hash==hash((k=e.key )|key.equals ) k ) ) { V oldValue=e.value; e .值=值; e .记录访问(this; 返回载荷值; } }模具计数; addentry(hash,key,value,I ); 返回空值; }/* * * addsanewentrywiththespecifiedkey, valueandhashcodeto * thespecifiedbucket.itistheresponsibilityofthis * methodtoresizethetableifappropriate.* * subclassoverridesthistoalterthebehaviorofputmethod.*/voidaddentry (int hash,K key,V value,int bucketIndex ) {EntryK,} if(size=threshold ) resize(2*table.Length ); } 1.8的put方法

publicvput(kkey,V value ) returnputval ) hash ) key,key,value,false,true ); }/* * * implements map.putandrelatedmethods.* * @ paramhashhhashforkey * @ paramkeythekey * @ paramvaluethevaluetoput * @ don ' tchangeexistingvalue * @ paramevictiffalse,thetableisincreationmode.* @ returnpreviousvalue ornullifnone */finalvpupure NodeK,V p; int n,I; if () tab=table )==null||(n=tab.Length )=0) n=(tab=resize ) ).length; if () p=tab(I=(n-1 ) hash]] ) null (tab ) I )=new node (hash,key,value,null ); else { NodeK,V e; k; if(p.hash==hash ) (k=p.key )==key||(key!=nullkey.equals(k ) ) (e=p; elseif(pinstanceoftreenode ) e=(treenodek,v ) p ).puttreeval ) this,tab,hash,key,value ); else{for(intbincount=0; binCount () if ) (e=p.next ) null ) ) p.next=newnode ) hash,key,value,null ); if (bincount=tree ify _ threshold-1 )/-1for1STTreeifybin(tab,hash ); 布雷克; (if ) e.hash==hash((k=e.key )==key||(key!=nullkey.equals(k ) ) (break; p=e; }if(e!=null (//existingmappingforkeyvoldvalue=e.value; if (! olyifabsent|||old value==null (e.value=value; afternodeaccess(e; 返回载荷值; } }模具计数; 大小阈值(if )大小); 自动识别(evict; 返回空值; }参照报道

3359 blog.csdn.net/lovezhaohaimig/article/details/86595113

总结网上说的话

jdk7数组单链表jdk8数组(单链表红黑树) ) ) ) ) ) )。

jdk7链表头插jdk8链表尾插

如果在头部插入: resize后插入传输数据,则无需遍历链表并将其插入末尾

头插:最近因put的可能性等被获取,头插遍历到链表的头时一致

在头部插入: resize后,链表可能会反转; 同时resize可能会产生循环链

jdk7先扩展,put jdk8先put,然后扩展(why? 有什么区别吗? )

jdk7计算混列运算多jdk8计算混列运算少

jdk7受rehash的影响,调整了jdk8后,变为(起始位置) or (起始位置旧容量)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。