HashMap之tableSizeFor简单解析

HashMap之tableSizeFor简单解析

  • 一、源码及提前知识了解
  • 二、举例理解源码
    • 1.出入值为16时
      • 1.1第一次对其进行的位运算
      • 1.2 第二次对其进行位运算
      • 1.3 第三次对其进行位运算
      • 1.4 返回结果
    • 2.出入值为17时
      • 2.1第一次对其进行的位运算
      • 2.2第二次对其进行的位运算
      • 2.3第三次对其进行的位运算
      • 2.4 返回结果
    • 三 、总结

一、源码及提前知识了解

最近看了下HashMap源码,看到tableSizeFor方法,便学习了下。
源码如下图所示:
HashMap之tableSizeFor简单解析_第1张图片
为了方便我将其粘贴出来,并用main方法调用
HashMap之tableSizeFor简单解析_第2张图片
tableSizeFor方法中,运用了两个运算符,这里做下简要介绍

1.>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。
按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。其他结构和>>相似。
2.“|”表示的是或运算,即两个二进制数同位中,只要有一个为1则结果为1,若两个都为1其结果也为1,换句话说就是取交集。

二、举例理解源码

接下来以2个输入值作为例子:

1.出入值为16时

进入代码,cap-1后为15(这里为什么要-1,后面会有总结)
在这里插入图片描述

1.1第一次对其进行的位运算

第一次对其进行的位运算
HashMap之tableSizeFor简单解析_第3张图片
即:
15二进制为0000 1111将其向又移1位变为0000 0111并与0000 1111进行或运算:在这里插入图片描述

1.2 第二次对其进行位运算

第二次对其进行位运算
HashMap之tableSizeFor简单解析_第4张图片
即:
n二进制为0000 1111将其向又移2位变为0000 0011并与0000 1111进行或运算
HashMap之tableSizeFor简单解析_第5张图片

1.3 第三次对其进行位运算

第三次对其进行位运算
HashMap之tableSizeFor简单解析_第6张图片
即:
n二进制为0000 1111将其向又移4位变为0000 0000并与0000 1111进行或运算
HashMap之tableSizeFor简单解析_第7张图片
之后的运算皆为0000 1111与0000 0000进行运算这里不进行赘述

1.4 返回结果

此时n为0000 1111即15,按返回逻辑返回为n+1,即16
在这里插入图片描述

2.出入值为17时

由于对17进行了-1的

2.1第一次对其进行的位运算

第一次对其进行的位运算
HashMap之tableSizeFor简单解析_第8张图片
即:
16二进制为0001 0000将其向又移1位变为0000 1000并与0001 0000进行或运算:HashMap之tableSizeFor简单解析_第9张图片

2.2第二次对其进行的位运算

第二次对其进行的位运算
HashMap之tableSizeFor简单解析_第10张图片
即:
n二进制为0001 1000将其向又移2位变为0000 0110并与0001 1000进行或运算:HashMap之tableSizeFor简单解析_第11张图片

2.3第三次对其进行的位运算

第三次对其进行的位运算
HashMap之tableSizeFor简单解析_第12张图片
即:
n二进制为0001 1110将其向又移4位变为0000 001并与0001 110进行或运算:在这里插入图片描述之后的运算皆为0001 1111与0000 0000进行运算这里不进行赘述

2.4 返回结果

此时n为0001 1111即31,按返回逻辑返回为n+1,即32
在这里插入图片描述

三 、总结

由此可以看出,上述传入16时,int n = cap - 1;的作用,即按当前算法缺少int n = cap - 1;时,最后输出值则会大一倍,即32,所以要进行int n = cap - 1;的操作,就是为了防止传入值与阀门值相通时,就会被放大一倍的情况发生。
其实只看开头和结尾不难看出,其核心逻辑就是进行补1的操作,即0000 1000 经过运算后变为0000 1111,在最后输出时候在进行加一的操作,变为0001 0000完成计算。

你可能感兴趣的:(java)