数学知识复习
3360左移运算符,num 1,相当于num乘以2来弥补0。示例:3 2将数字3向左移动2位,将3转换为二进制数0000 0000 0000 000 000 0011,然后移出高位(左侧)的两个零,并将其他数字向左移动2位,最后移至低位(右侧)。最后的结果是0000 0000 0000 0000 0000 0000 0000 0000 0000 1100,所以十进制转换是12。数学意义:在数不溢出的前提下,无论是正数还是负数,左移一位相当于2的1次方,左移n位相当于2的n次方。3360右移运算符示例:11 2将数字11右移2位,11的二进制形式为:0000 0000 0000 0000 000 0000 1011,然后移出低位的最后两位数字,因为数字是正数,所以在高位用零填充。最后的结果是0000 0000 0000 0000 0000 0000 0000 0000 0000 0010。十进制转换是3。数学意义:向右移一位相当于除2,向右移n位相当于除2的n次方。这是商。我不想要剩下的。3360无符号右移,忽略符号位,空位用0填充。在二进制形式中,所有数字都向右移动相应的位数,低位被移出(丢弃),高位用零填充。对于正数,它与有符号右移相同,但对于负数,它是不同的。其他结构和相似之处。% :模运算的余数是一个简单的余数运算。位异或第一个操作数的第n位与第二个操作数的第n位相反,那么结果的第n位也是1,否则000 0=0,1 0=1,0 1=1,1 1=0 3360和第一个操作数的第n位被定位。那么结果的第n个值也是1,否则就是000=0,01=0,10=0,11=1 | 3360或者第一个操作数的第n个值位于第二个操作数的第n位。只要其中一个为1,结果的第n个值也为1,否则为00|0=0,0| 1=1,1。那么结果的第n位为0,反之亦然,即取逆运算(一元运算符:只运算一个数)~1=0,~0=1HashMap算法。
首先,要理解一个概念,HashMap中桶的位置是通过对Key的哈希值和数组的长度取模来计算的。
具体细节我就不说了,但我假设大家默认都知道这一点。
模数可以更改为:哈希码(长度-1)
看看JDK8中的哈希算法:
静态最终整数散列(对象键){ 0
int h;
return (key==null)?0 :(h=key . hashcode())^(h 16);
}
首先使用密钥的hashCode算法,然后对16进行异或运算和右移运算。
在分析上面的异或运算和右移运算之前,我们需要先看另一件事。什么事?是HashMap如何根据哈希值找到数组种类的对象。让我们看看get方法的代码:
让我们看看代码中注释下面的行:first=tab[(n-1) hash])。
哈希值是通过从数组长度中减去一来计算的。这一行代码就是之前的哈希方法被移位和异或的原因。
* *我们来分析一下:* *
首先假设有一种情况,对象A的hashCode为1000010001110001000011111100000,对象B的hashCode为011011001100000。
如果数组的长度是16,也就是15和operation(前面提到的hashCode (length-1))的数字,你会发现结果都是0。这个散列结果太令人失望了。显然不是一个好的哈希算法。
但是如果我们将hashCode值向右移动16位,也就是取int类型的一半,只需将二进制数减半。并且使用按位异或运算(如果两个数对应的位置相反,结果会是1,否则会是0),这样就可以避免上面的情况。简而言之,尽量干扰hashCode的低16位,因为低16位确实参与了运算。
我不知道这个解释是否简单明了。经过自己的思考和分析,我也明白了这个代码设计的初衷,也会感叹设计者的精妙。