为什么Java的hash表的长度一直是2的指数次幂?为什么这个(hash&(h-1)=hash%h)位运算公式等价于取余运算?
Posted chaeyeon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么Java的hash表的长度一直是2的指数次幂?为什么这个(hash&(h-1)=hash%h)位运算公式等价于取余运算?相关的知识,希望对你有一定的参考价值。
1.什么是hash表?
答:简单回答散列表,运算在hash结构散列(分散)存放。
2.如何散列排布,如果均匀排布?
答:取余运算
3.Java中如何实现?
答:hash&(h-1)
4.为什么hash&(h-1)=等价于hash%h
java的h(表长)一定是2的指数次幂,2的指数次幂2n
2n的结果:一定长这样10000...(n个0)
2n-1的结果:一定这样1111(n-1)个1
举个例子:
当h=16,对应的二进制:00010000
h-1=15,对应的二进制:00001111
可以知道所有的数与00001111进行&运算
高位都是0,低位取决于这个数的后四位(可能为0,也可能为1)
因此:(24-1)& hash=0 ~(24-1)之间=hash%(24)
只要知道是取余就行这种写法就行。只是对cpu指令的优化,
5.总结取余是为了散列分布,而hash桶的长度以2的指数被增长,可以使用位运算代替取余运算(显示的告诉计算机采用位运算,但是你去取余计算机应该也是这么用位去算的,.net里就是直接取余的,但表长也是2的指数倍)
hahs结构的重点算法应该是求hashcode,比如字符串,既要保证运算相同的串值的hash相同,又要使hash值尽量不同(不然也不能散列分布),就要去遍历串来计算hahscode,而hashcode一般占4字节
以上是关于为什么Java的hash表的长度一直是2的指数次幂?为什么这个(hash&(h-1)=hash%h)位运算公式等价于取余运算?的主要内容,如果未能解决你的问题,请参考以下文章
Java集合 -- HashMap底层实现HashMap 的长度为什么是2的幂次方ConcurrentHashMap 和 HashtableConcurrentHashMap线程安全的实现