五、源码分析之常用方法解读1、tableSizeFor方法解读/** * 返回给定目标容量的 2 次方 。*/static final int tableSizeFor(int cap) { // cap = 10int n = cap - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;// 小于0就是1,如果大于0在判断是不是超过最大容量就是n=15+1 = 16,超过就按最大容量return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}
以cap为10
为例:(右移规则为:无符号位右移)
【HashMap底层原理及jdk1.8源码解读】10的二进制为:0000 0000 0000 0000 0000 0000 0000 1010
执行int n = cap - 1;
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1001
执行n |= n >>> 1;(先进行右移,结果和原来的数进行或运算[==有1则1==])
0000 0000 0000 0000 0000 0000 0000 10010000 0000 0000 0000 0000 0000 0000 0100n>>1结果————————————————————0000 0000 0000 0000 0000 0000 0000 1101n |= n >> 1 结果
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1101
执行n |= n >>> 2;
0000 0000 0000 0000 0000 0000 0000 1101
0000 0000 0000 0000 0000 0000 0000 0011n>>2结果
————————————————————0000 0000 0000 0000 0000 0000 0000 1111n |= n >> 2 结果
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1111
执行n |= n >>> 4;
0000 0000 0000 0000 0000 0000 0000 1111
0000 0000 0000 0000 0000 0000 0000 0000n>>4结果
————————————————————0000 0000 0000 0000 0000 0000 0000 1111n |= n >> 4 结果
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1111
执行n |= n >>> 8;
0000 0000 0000 0000 0000 0000 0000 1111
0000 0000 0000 0000 0000 0000 0000 0000n>>8结果
————————————————————0000 0000 0000 0000 0000 0000 0000 1111n |= n >> 8 结果
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1111
执行n |= n >>> 16;
0000 0000 0000 0000 0000 0000 0000 1111
0000 0000 0000 0000 0000 0000 0000 0000n>>16结果
————————————————————0000 0000 0000 0000 0000 0000 0000 1111n |= n >> 16 结果
二进制结果为:0000 0000 0000 0000 0000 0000 0000 1111
我们会发现,当数小的的时候进行到4时就不会变了我们得到的值为15,即输入10,经过此方法后得到15
。遇到大的数才会明显,大家可以找个大的数字进行试试就是先右移
在进行或运算
。最后进行三门运算进行+1
操作,最后结果为16=2^4
2、hash方法解读static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}
先判断key是否为空,若为空则返回0 。上面说了HashMap仅支持一个key为null的 。若非空,则先计算key的hashCode值,赋值给h,然后把h右移16位,并与原来的h进行异或处理(相同为1,不同为0
) 。注释进行谷歌翻译:计算 key.hashCode() 并传播(XOR)更高位的哈希降低 。由于该表使用二次幂掩码,因此仅在当前掩码之上位变化的散列集将始终发生冲突 。(已知的例子是在小表中保存连续整数的 Float 键集 。)因此,我们应用了一种变换,将高位的影响向下传播
。在位扩展的速度、实用性和质量之间存在折衷 。因为许多常见的散列集已经合理分布(所以不要从传播中受益),并且因为我们使用树来处理 bin 中的大量冲突,我们只是以最简单的方式对一些
经验总结扩展阅读
- 节电器的工作原理是什么
- 我的 Kafka 旅程 - Producer
- 小电流接地选线装置原理
- 价值观的导向作用原理及方法论
- 可控硅工作原理
- 非常芯地漏缺点是什么?
- 热玛吉是什么原理
- 单克隆抗体的原理
- 电机调速器的工作原理
- Java 读写锁 ReadWriteLock 原理与应用场景详解