今天在看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