Java 自增自減運算符和移位運算符介紹

摘自 JavaGuide (「Java學習+面試指南」一份涵蓋大部分 Java 程序員所需要掌握的核心知識。準備 Java 面試,首選 JavaGuide!)

自增自減運算符

在寫代碼的過程中,常見的一種情況是需要某個整數類型變量增加 1 或減少 1,Java 提供了一種特殊的運算符,用於這種表達式,叫做自增運算符(++)和自減運算符(--)。

++ 和 -- 運算符可以放在變量之前,也可以放在變量之後,當運算符放在變量之前時(前綴),先自增/減,再賦值;當運算符放在變量之後時(後綴),先賦值,再自增/減。例如,當 b = ++a 時,先自增(自己增加 1),再賦值(賦值給 b);當 b = a++ 時,先賦值(賦值給 b),再自增(自己增加 1)。也就是,++a 輸出的是 a+1 的值,a++輸出的是 a 值。用一句口訣就是:“符號在前就先加/減,符號在後就後加/減”。

移位運算符

移位運算符是最基本的運算符之一,幾乎每種編程語言都包含這一運算符。移位操作中,被操作的數據被視爲二進制數,移位就是將其向左或向右移動若干位的運算。

移位運算符在各種框架以及 JDK 自身的源碼中使用還是挺廣泛的,HashMap(JDK1.8) 中的 hash 方法的源碼就用到了移位運算符:

static final int hash(Object key) {
    int h;
    // key.hashCode():返回散列值也就是hashcode
    // ^ :按位異或
    // >>>:無符號右移,忽略符號位,空位都以0補齊
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  }

在 Java 代碼裏使用 <<>>>>>轉換成的指令碼運行起來會更高效些。

掌握最基本的移位運算符知識還是很有必要的,這不光可以幫助我們在代碼中使用,還可以幫助我們理解源碼中涉及到移位運算符的代碼。

Java 中有三種移位運算符:

  • << :左移運算符,向左移若干位,高位丟棄,低位補零。x << 1,相當於 x 乘以 2(不溢出的情況下)。
  • >> :帶符號右移,向右移若干位,高位補符號位,低位丟棄。正數高位補 0,負數高位補 1。x >> 1,相當於 x 除以 2。
  • >>> :無符號右移,忽略符號位,空位都以 0 補齊。

由於 doublefloat 在二進制中的表現比較特殊,因此不能來進行移位操作。

移位操作符實際上支持的類型只有intlong,編譯器在對shortbytechar類型進行移位前,都會將其轉換爲int類型再操作。

如果移位的位數超過數值所佔有的位數會怎樣?

當 int 類型左移/右移位數大於等於 32 位操作時,會先求餘(%)後再進行左移/右移操作。也就是說左移/右移 32 位相當於不進行移位操作(32%32=0),左移/右移 42 位相當於左移/右移 10 位(42%32=10)。當 long 類型進行左移/右移操作時,由於 long 對應的二進制是 64 位,因此求餘操作的基數也變成了 64。

也就是說:x<<42等同於x<<10x>>42等同於x>>10x >>>42等同於x >>> 10

左移運算符代碼示例

int i = -1;
System.out.println("初始數據: " + i);
System.out.println("初始數據對應的二進制字符串: " + Integer.toBinaryString(i));
i <<= 10;
System.out.println("左移 10 位後的數據 " + i);
System.out.println("左移 10 位後的數據對應的二進制字符 " + Integer.toBinaryString(i));

輸出:

初始數據: -1
初始數據對應的二進制字符串: 11111111111111111111111111111111
左移 10 位後的數據 -1024
左移 10 位後的數據對應的二進制字符 11111111111111111111110000000000

由於左移位數大於等於 32 位操作時,會先求餘(%)後再進行左移操作,所以下面的代碼左移 42 位相當於左移 10 位(42%32=10),輸出結果和前面的代碼一樣。

int i = -1;
System.out.println("初始數據: " + i);
System.out.println("初始數據對應的二進制字符串: " + Integer.toBinaryString(i));
i <<= 42;
System.out.println("左移 10 位後的數據 " + i);
System.out.println("左移 10 位後的數據對應的二進制字符 " + Integer.toBinaryString(i));

右移運算符使用類似,篇幅問題,這裏就不做演示了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章