首页 > 编程知识 正文

redis hash原理,如何避免hash冲突

时间:2023-05-06 14:24:44 阅读:21592 作者:1276

文章目录HashMap中的hash冲突1.7概述了HashMap

HashMap的hash碰撞1.7介绍

混列映射使用所谓的“混列算法”来确定每个元素的存储位置。 当程序执行map.put(String,Obect )方法时,系统调用string的hashCode )方法以获取其hashCode值——,每个Java对象都有hashCode 得到此对象的hashCode值后,该hashCode值将确定元素的存储位置。

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; //判断当前确定的索引位置是否有相同hashcode和相同key的元素,如果有相同hashcode和相同key的元素,新值将复盖原始旧值并返回旧值。 //如果存在相同的hashcode,他们决定的索引位置相同,那时判断他们的key是否相同,否则,那时就会发生hash冲突。 //Hash冲突后,HashMap中的单个bucket存储条目链,而不是条目链。 //系统必须按顺序遍历每个条目,直到找到想要搜索的条目。 ——如果要搜索的Entry位于该Entry链的末尾,//该系统必须循环到末尾才能找到元素。 if(e.hash==hash((k=e.key )|key.equals ) k ) ) { V oldValue=e.value; e .值=值; 返回载荷值; } }模具计数; addentry(hash,key,value,I ); 返回空值; 当系统决定保存HashMap中的key-value对时,根本不考虑Entry中的value,而是只根据key计算并确定每个Entry的存储位置。 这也说明了前面的结论。可以把 Map 集合中的 value 当成 key 的附属,当系统决定了 key 的存储位置之后,value 随之保存在那里即可

解决哈希值冲突问题的两种方法:

链表方法是将具有相同散列值的对象组织为一个链表,并将其放在与散列值对应的槽中。 如果某个时隙比特已经被一个探测算法占用,则开放地址方法继续搜索下一个可用的时隙比特。 HashMap采用链表法,链表是单向链表。

voidaddentry(inthash,K key,V value,int bucketIndex ),V e=table[bucketIndex]; table[bucketIndex]=new EntryK,v(hash,key,value,e ); if(size=threshold ) resize(2*table.Length ); 始终将新添加的Entry对象放置在table数组的bucketIndex索引中。 如果—— bucket索引中已经有Entry对象,则新添加的Entry对象将指向原始Entry对象。 将生成“入口链”。 如果bucketIndex索引中没有Entry对象,即上面的程序代码中的e变量为null,即新插入的Entry对象指向null,即没有生成Entry链。 HashMap中没有发生hash冲突,没有形成单链表时,HashMap查找元素快,get )方法可以直接位于元素中,但出现单链表后,单个bucket ——如果要搜索的条目位于该条目链的末尾,直到找到要搜索的条目,则该条目是第一个放在bucket中的。 系统必须循环到底才能找到要素。 创建HashMap时,存在默认的“加载因子”(load factor )。 默认值为0.75,这是时间和空间成本之间的折衷。 较大的加载因子会减少Hash表)或其Entry数组占用的内存空间,但会增加查询数据的时间开销。 查询是最常见的操作)降低HashMap的get负载率可以提高数据查询的性能,但会增加Hash表占用的内存空间。

HashMap概述了基于哈希表的HashMap接口的实现。 此实现提供了所有可选的映射操作,允许使用空值和空键。 (HashMap类与Hashtable几乎相同,除了允许异步和空值使用。 )并不保证这种映射的顺序,特别是不保证其顺序永久不变。

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