最近看HashMap源碼,遇到了這樣一段代碼:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
先回想下如下知識:
1.十進制轉(zhuǎn)二進制
原理:給定的數(shù)循環(huán)除以2绒怨,直到商為0或者1為止纯赎。將每一步除的結(jié)果的余數(shù)記錄下來,然后反過來就得到相應的二進制了南蹂。
比如8轉(zhuǎn)二進制犬金,第一次除以2等于4(余數(shù)0),第二次除以2等于2(余數(shù)0)碎紊,第三次除以2等于1(余數(shù)0)佑附,最后余數(shù)1,得到的余數(shù)依次是0 0 0 1 仗考,
反過來就是1000音同,計算機內(nèi)部表示數(shù)的字節(jié)長度是固定的,比如8位秃嗜,16位权均,32位。所以在高位補齊锅锨,java中字節(jié)碼是8位的叽赊,所以高位補齊就是00001000.
寫法位(8)10=(00001000)2;
代碼實現(xiàn):
package sourceCode.hashMap;
public class mapHashCodeTest {
public static void main(String[] args) {
String str = toBinary(8);
System.out.println(str);
}
static String toBinary(int num) {
String str = "";
while (num != 0) {
str = num % 2 + str;
num = num / 2;
}
return str;
}
}
運行結(jié)果:1000
2.二進制轉(zhuǎn)十進制
計算也很簡單必搞,比如8的二進制表示位00001000必指,去掉補齊的高位就是1000.此時從個位開始計算2的冪(個位是0,依次往后推)乘以對應位數(shù)上的數(shù)恕洲,然后得到的值想加
于是有了塔橡,(2的0次冪)0+(2的1次冪)0+(2的2次冪)0+(2的3次冪)1 = 8
代碼實現(xiàn),直接調(diào)用Integer.parseInt("",2);
1 System.out.println(Integer.parseInt("1000",2));
運行結(jié)果:8
3.位異或運算(^)
運算規(guī)則是:兩個數(shù)轉(zhuǎn)為二進制霜第,然后從高位開始比較葛家,如果相同則為0,不相同則為1泌类。
比如:8^11.
8轉(zhuǎn)為二進制是1000癞谒,11轉(zhuǎn)為二進制是1011.從高位開始比較得到的是:0011.然后二進制轉(zhuǎn)為十進制,就是Integer.parseInt("0011",2)=3;
延伸:
4.位與運算符(&)
運算規(guī)則:兩個數(shù)都轉(zhuǎn)為二進制刃榨,然后從高位開始比較弹砚,如果兩個數(shù)都為1則為1,否則為0喇澡。
比如:129&128.
129轉(zhuǎn)換成二進制就是10000001迅栅,128轉(zhuǎn)換成二進制就是10000000。從高位開始比較得到晴玖,得到10000000读存,即128.
5.位或運算符(|)
運算規(guī)則:兩個數(shù)都轉(zhuǎn)為二進制为流,然后從高位開始比較,兩個數(shù)只要有一個為1則為1让簿,否則就為0敬察。
比如:129|128.
129轉(zhuǎn)換成二進制就是10000001,128轉(zhuǎn)換成二進制就是10000000尔当。從高位開始比較得到莲祸,得到10000001,即129.
6.位非運算符(~)
運算規(guī)則:如果位為0椭迎,結(jié)果是1锐帜,如果位為1,結(jié)果是0.
比如:~37
在Java中畜号,所有數(shù)據(jù)的表示方法都是以補碼的形式表示缴阎,如果沒有特殊說明,Java中的數(shù)據(jù)類型默認是int简软,int數(shù)據(jù)類型的占用四個字節(jié)蛮拔,一個字節(jié)是8位,就是32位
bit:位痹升,一個二進制數(shù)據(jù)0或1建炫,是1bit
byte:字節(jié),存儲空間的基本的單元疼蛾,1byte=8bit
一個英文占一個字節(jié)肛跌,1字母=1byte=8bit
一個中文占兩個字節(jié),1漢字=2byte=16bit
byte:一個字節(jié)(8位)(-128~127)(-2的7次方到2的7次方-1)
short:兩個字節(jié)(16位)(-32768~32767)(-2的15次方到2的15次方-1)
int:四個字節(jié)(32位)(一個字長)(-2147483648~2147483647)(-2的31次方到2的31次方-1)
long:八個字節(jié)(64位)(-9223372036854774808~9223372036854774807)(-2的63次方到2的63次方-1)
float:四個字節(jié)(32位)(3.402823e+38 ~ 1.401298e-45)(e+38是乘以10的38次方察郁,e-45是乘以10的
負45次方)
double:八個字節(jié)(64位)(1.797693e+308~ 4.9000000e-324)
8轉(zhuǎn)為二進制是100101.
補碼后為: 00000000 00000000 00000000 00100101
取反為: 11111111 11111111 11111111 11011010
因為高位是1惋砂,所以原碼為負數(shù),負數(shù)的補碼是其絕對值的原碼取反绳锅,末尾再加1。
因此酝掩,我們可將這個二進制數(shù)的補碼進行還原: 首先鳞芙,末尾減1得反碼:11111111 11111111 11111111 11011001 其次,將各位取反得原碼:
00000000 00000000 00000000 00100110期虾,此時二進制轉(zhuǎn)原碼為38
所以~37 = -38.