常見的運算子:
& 與
兩個數都轉為二進位制,然後從高位開始比較,如果兩個數都為1則為1,否則為0。
或(|)
兩個數只要有一個為1則為1,否則就為0。
非(~),反義詞
如果位為0,結果是1,如果位為1,結果是0
異或 (^)
相同為0,不相同則為1
說明:以上運算子均為位運算子,計算機中儲存的時數字的補碼,正數的補碼為本身,負數的補碼是:符號位不變,其他取反加一。
左移運算子<<
-
規則:
按二進位制形式把所有的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。
當左移的運算數是int 型別時,每移動1位它的第31位就要被移出並且丟棄;
當左移的運算數是long 型別時,每移動1位它的第63位就要被移出並且丟棄。
當左移的運算數是byte 和short型別時,將自動把這些型別擴大為 int 型。
-
數學意義:
在數字沒有溢位的前提下,對於正數和負數,左移一位都相當於乘以2的1次方,左移n位就相當於乘以2的n次方。 3 << 2,其實就是3*2的二次方
右移運算子(>>)
-
規則:
按二進位制形式把所有的數字向右移動對應的位數,低位移出(捨棄),高位的空位補符號位,即正數補零,負數補1 當右移的運算數是byte 和short型別時,將自動把這些型別擴大為 int 型。
例如,如果要移走的值為負數,每一次右移都在左邊補1,如果要移走的值為正數,每一次右移都在左邊補0,這叫做符號位擴充套件 (保留符號位)(sign extension ),在進行右移
操作時用來保持負數的符號。
- 數學意義:除2
無符號右移(>>>)
直接在高位補0,低位刪除。
int i=-7;
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(i>>>2));
System.out.println(Integer.toBinaryString(i>>2));
執行結果:
11111111111111111111111111111001
111111111111111111111111111110
11111111111111111111111111111110
複製程式碼
從以上執行結果可以看出>>> 和>>的區別
例子:
hashmap原始碼中,計算key的hashcode方法如下
/**
* Computes key.hashCode() and spreads (XORs) higher bits of hash
* to lower. Because the table uses power-of-two masking, sets of
* hashes that vary only in bits above the current mask will
* always collide. (Among known examples are sets of Float keys
* holding consecutive whole numbers in small tables.) So we
* apply a transform that spreads the impact of higher bits
* downward. There is a tradeoff between speed, utility, and
* quality of bit-spreading. Because many common sets of hashes
* are already reasonably distributed (so don't benefit from
* spreading), and because we use trees to handle large sets of
* collisions in bins, we just XOR some shifted bits in the
* cheapest possible way to reduce systematic lossage, as well as
* to incorporate impact of the highest bits that would otherwise
* never be used in index calculations because of table bounds.
*/
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
複製程式碼
key的hashcode無符號右移了16位,然後與key的hashcode異或位運算。這種方法高效的讓hashcode的高位和低位進行了一次異或運算。據說可以產生更加隨機的hashcode,但是我並看不出來為什麼,如果有大神做過測試或者知道其中的原理可以留言。 但是可以知道的是,這種運算子在原始碼中很實用。