为什么HashTable的初始化因子是11,HashMap却是16

关于HashTable和HashMap的不同点这里就不再说明,网上很多;

今天突然对这个初始化因子不通的问题有了兴趣,以前只知道不一样,从没想过为什么不一样,然后查了半天,感觉相关文章说的很少,想自己来记录一下

关于HashTable和HashMap,最重要的不过是hash了,而hash的目的就是为了尽可能的减少寻址冲突,下面边看源码变分析(1.8)

1.HashTable

使用外部对象key的hashCode()方法,经过和数组大小取模获取下标。

那么这里为什么用11,而不是用16呢(HashMap的是16)?

网上有不少说的论证是如下图(【集合我能讲两小时028】为什么hashtable的扩容方式选择为2n+1?_檀越剑指大厂的博客-CSDN博客_hashtable扩容为什么是2n+1为什么hashtable的扩容方式选择为2n+1?为了均匀分布,降低冲突率。首先,Hashtable的初始容量为11。Index的计算方式为: int index = (hash & 0x7FFFFFFF) % tab.length;常用的hash函数是选一个数m取模(余数),这个数在课本中推荐m是素数,但是经常见到选择m=2n,因为对2n求余数更快,并认为在key分布均匀的情况下,key%m也是在[0,m-1]区间均匀分布的。但实际上,key%m的分布同m是有关的。证明如下:key%mhttps://blog.csdn.net/qyj19920704/article/details/123322666?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-1-123322666-null-null.pc_agg_new_rank&utm_term=hashtable%E4%B8%BA%E4%BB%80%E4%B9%88%E9%BB%98%E8%AE%A4%E4%B8%BA11&spm=1000.2123.3001.4430

 中间的证明,我不是很认可,因为他举例的是和 m有公约数的key,用一定条件的key来举证在所有m的位置不均匀本身就是断章取义,比如:m=9,那么公约数=3,那么key的范围只是局限于如(12、15、18、21、24、27。。),所在位置index也就是 3、6、0;但是如果key为任意数,则index的位置为 1、2、3、4、5、6、7、8、0,均匀分布;所以举证不成立;

那是不是结果就不正确呢,我认为不是,上面所说的前提的key是均匀分布的,但是实际上怎么样呢?我们知道这个key在HashTable中,是根据hashcode()方法来的,方法是属于其他对象的,并不能确定一定是均匀的,所以我们认为key不一定是均匀分布

这时候我们用一个质数(至少也是个奇数)作为桶的数量,能更大程度的减少冲突

而初始化的值也不适合过大(影响空间),所以是11

2.HashMap

HashTable是取模,HashMap却是 & ,所以只能是2的n次方(二进制都是1),这样才会尽量减少冲突,hash方法是HashMap内部的,如下

把高位的变化,通过异或运算,也映射到低位,这样,在 & 的时候才能减少冲突 

 参考自:language agnostic - Why should hash functions use a prime number modulus? - Stack Overflowhttps://stackoverflow.com/questions/1145217/why-should-hash-functions-use-a-prime-number-modulus

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值