今天在看Java8的HashMap底层原理的时候看到多处操做二进制数的地方。虽然平时写代码不怎么用到二进制的操做,建议之后还要往二进制操做上靠一靠,由于他确实能提升效率,并且是代码更为简洁。在此,我在这里说下它的定义和做用,不对的地方但愿你们指正。java
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
复制代码
取key的hashCode,各种型的hashCode实现方式不一样,如Integer和String,代码以下,此处咱们不针对hashCode()深究bash
// Integer
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
// String
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
复制代码
知足公式:(X^X=0 ,X^0=X)ide
交换律:A^B=B^Aui
结合律:A^B^C=A^(B^C)=(A^B)^Cspa
自反律:A^B^B=A^0=Acode
7^2 7^7 7^0
0111 0111 0111
0010 0111 0000
---- ---- ----
0101 = 5 (十进制) 0000 = 0 0111 = 7
复制代码
异或可在不引入第三个数的状况下交换两个数,以下代码源码
if (a != b) {
a ^= b;
b ^= a;
a ^= b;
}
复制代码
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
......
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
......
}
复制代码
7&2 7&7 7&0
0111 0111 0111
0010 0111 0000
---- ---- ----
0010 = 2 (十进制) 0111 = 7 0000 = 0
----
复制代码
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
复制代码
在实例化HashMap时,在tableSizeFor(int cap)中使用了“|”,n |= n >>> 1;等价于n = n | (n >>> 1);方法的做用我会在接下来的HashMap源码解析中提到。hash