在上一篇Java 中HashMap详解(含HashTable, ConcurrentHashMap)中提到在map.put(key, value)的过程中,计算完key的hash值, 是通过hash & (n-1)来得出该元素在Node数组中的下标的,其中n是Node数组的长度。 其实我们更容易想到的是hash % n,这样刚好会得到0~n-1之间的数字,可以用作数组下标。那么为何此处是用...
高效取余运算(n-1)&hash原理探讨 Java的HashMap源码中用到的(n-1)&hash这样的运算,查找发现这是一种高效的求余数的办法,但其中的原理是什么呢为什么可以这么做呢? 先上结论:假设被除数是x,对于除数是2n的取余操作x%2n,都可以写成x&(2n-1),位运算效率高! eg:259%8=259&7=32591000000117000000111259&7=0...
也就是说,如果数组长度为2的n次幂时,模运算 % 可以变换为按位与 & 运算。那么为什么用(n-1)&hash而不是用hash%n呢,因为在计算机中 & 的效率比 % 高很多。
规则是index = hash % n(index: 数组下标,hash:key的哈希值,n:table的容量) 保证了index的值范围:0~ n-1,即是有效的数组下标 但是为了性能的考虑,选择了用位运算的方式实现了整除取余的功能 只有在n是2的n次方的情况,hash % n =(n-1) &hash 结论:在n是2的x次方的情况,(n-1) & hash完成了整除...
HashMap里的 (n - 1) & hash,在HashMap的putVal方法中,HashMap使用了(n-1)&hash的方式取数组下标,这是位运算,位运算比取模运算效率更高,但并不是所有取模运算都满足位运算,HashMap如此使用是因为当n是2的幂次方(2、4、8、16、32、64……)时,有公式:(n-1)&ha
高效取余运算(n-1)&hash原理探讨 Java的HashMap源码中用到的(n-1)&hash这样的运算,查找发现这是一种高效的求余数的办法,但其中的原理是什么呢为什么可以这么做呢? 先上结论:假设被除数是x,对于除数是2n的取余操作x%2n,都可以写成x&(2n-1),位运算效率高!
那这有啥用呢?重点来了,因为n必为2^n,所以自n-1的最高位往前数,全部都是n的倍数,咱们计算余数肯定必须要把整数倍全部减掉剩下的才是余数啊,又因为n-1全部为1,所以能将除n的整数倍剩下余数完全保留下来,这就是公式能成立的原因!
HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过(n-1)&hash判断当前元素存放的位置(这里的n指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的hash 值以及key 是否相同,如果相同的话,直接覆盖,不相同就通过...
hash(object)%N 1.一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) ; 2.由于QPS升高,我们需要添加多一台服务器,这时候服务器是 N+1 台,映射公式变成了 hash(object)%(N+1) 。
这一现象就是我们所说的“抽屉原理”。抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理...