首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDK 源碼深度解析:Integer.toBinaryString() 位運算精妙實現

     編輯:Java 相關知識

面試真題還原

「請手寫 Integer.toBinaryString(int i) 的核心邏輯,不允許調用現成 API」

源碼還原

// JDK 1.8 源碼 java.lang.Integer
public static String toBinaryString(int i) {
    return toUnsignedString(i, 1); // shift=1 表示二進制
}

private static String toUnsignedString(int i, int shift) {
    char[] buf = new char[32];        // int 32 位,最多 32 個字符
    int charPos = 32;                 // 從尾部向前填充
    int radix = 1 << shift;           // 基數:二進制=2,八進制=8,十六進制=16
    int mask = radix - 1;             // 掩碼:二進制=1(0b1),八進制=7(0b111)...

    do {
        buf[--charPos] = digits[i & mask]; // 取最低位映射字符
        i >>>= shift;                    // 無符號右移
    } while (i != 0);

    return new String(buf, charPos, 32 - charPos);
}

// 字符映射表:0-9, a-z
final static char[] digits = {
    '0','1','2','3','4','5','6','7','8','9',
    'a','b','c','d','e','f','g','h','i','j',
    'k','l','m','n','o','p','q','r','s','t',
    'u','v','w','x','y','z'
};

核心邏輯圖解

以 i = 13 (0b1101) 為例,shift=1 (二進制):

初始:buf[32], charPos=32, mask=1, radix=2

第1輪:i=13 (1101)
  i & mask = 1 → buf[31] = '1'
  i >>>= 1 → i=6 (0110)
  charPos=31

第2輪:i=6 (0110)
  i & mask = 0 → buf[30] = '0'
  i >>>= 1 → i=3 (0011)
  charPos=30

第3輪:i=3 (0011)
  i & mask = 1 → buf[29] = '1'
  i >>>= 1 → i=1 (0001)
  charPos=29

第4輪:i=1 (0001)
  i & mask = 1 → buf[28] = '1'
  i >>>= 1 → i=0
  charPos=28

循環結束,返回 new String(buf, 28, 4) → "1101"

關鍵技術點

  1. 無符號右移 >>>:高位補 0,確保負數也能正確轉換(-1 → 32 個 1)
  2. 掩碼 & mask:提取最低有效位,通用於任意進制
  3. 字符緩衝區逆向填充:避免字符串拼接開銷,O(1) 空間
  4. do-while 保證 0 也能輸出 "0"

手寫面試版(精簡)

public static String toBinaryStringManual(int num) {
    if (num == 0) return "0";
    char[] buf = new char[32];
    int pos = 32;
    while (num != 0) {
        buf[--pos] = (num & 1) == 1 ? '1' : '0';
        num >>>= 1;
    }
    return new String(buf, pos, 32 - pos);
}

擴展:通用進制轉換

public static String toBaseString(int num, int base) {
    // base 必須是 2 的冪次:2, 4, 8, 16, 32...
    char[] buf = new char[32];
    int pos = 32;
    int shift = 31 - Integer.numberOfLeadingZeros(base); // log2(base)
    int mask = base - 1;
    do {
        int digit = num & mask;
        buf[--pos] = Character.forDigit(digit, base);
        num >>>= shift;
    } while (num != 0);
    return new String(buf, pos, 32 - pos);
}

總結

toBinaryString 展示了 JDK 開發者對 位運算、無符號移位、字符映射、緩衝區複用 的極致優化。面試手寫時,抓住 mask 提取低位 + >>> 右移 + 逆向填充 buf 三步曲,即可寫出正確、高效的實現。理解其通用化設計(shift/mask 參數化),更能舉一反三應對八進制、十六進制轉換題目。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved