整理一些 JDK 中 Integer 實用但不常用的方法
個人部落格:DoubleFJ の Blog
直接開搞。
toString
該方法進行了過載,一種是 toString(int i, int radix)
,另一個是 toString(int i)
。一個引數的方法就相當於 toString(int i, 10)
,看程式碼便知,何況其官網註釋也有:
public static String toString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
// int 32位
char buf[] = new char[33];
boolean negative = (i < 0);
int charPos = 32;
if (!negative) {
i = -i;
}
// 根據進製取餘轉換
while (i <= -radix) {
buf[charPos--] = digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = digits[-i];
if (negative) {
buf[--charPos] = '-';
}
return new String(buf, charPos, (33 - charPos));
}
不過該方法需注意: If the first argument is negative, the first element of the result is the ASCII minus character '-' ('\u005Cu002D'). If the first argument is not negative, no sign character appears in the result.
例如:
Integer.toString(-44, 2) // -101100
Integer.toBinaryString(-44) // 11111111111111111111111111010100
若是負數,用該方法求得的值只是正數前加了個 “-” 。
toBinaryString
類似的幾個方法也一併列出了。 toBinaryString(int i)
轉二進位制方法,toOctalString(int i)
轉八進位制方法,toHexString(int i)
轉十六進位制方法。
Integer.toBinaryString(-44) // 11111111111111111111111111010100
Integer.toOctalString(44) // 54
Integer.toHexString(44) // 2c
parseUnsignedInt
與 toString 方法一樣進行了過載。 parseUnsignedInt(String s)
與 parseUnsignedInt(String s, int radix)
這是 JDK 1.8 新增的方法,作用就是將字串引數解析為第二個引數指定的基數中的無符號整數。
Integer.parseUnsignedInt("11111111111111111111111111010100", 2) // -44
Integer.parseUnsignedInt("44", 10) // 44
Integer.parseUnsignedInt("44") // 44
decode
該方法將 String 解碼為整數。 接受指定語法的十進位制,十六進位制和八進位制數。原始碼如下:
public static Integer decode(String nm) throws NumberFormatException {
int radix = 10;
int index = 0;
boolean negative = false;
Integer result;
if (nm.length() == 0)
throw new NumberFormatException("Zero length string");
char firstChar = nm.charAt(0);
// Handle sign, if present
if (firstChar == '-') {
negative = true;
index++;
} else if (firstChar == '+')
index++;
// Handle radix specifier, if present
if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
index += 2;
radix = 16;
}
else if (nm.startsWith("#", index)) {
index ++;
radix = 16;
}
else if (nm.startsWith("0", index) && nm.length() > 1 + index) { // 0 後面長度要大於 1
index ++;
radix = 8;
}
if (nm.startsWith("-", index) || nm.startsWith("+", index))
throw new NumberFormatException("Sign character in wrong position");
try {
result = Integer.valueOf(nm.substring(index), radix);
result = negative ? Integer.valueOf(-result.intValue()) : result;
} catch (NumberFormatException e) {
// If number is Integer.MIN_VALUE, we'll end up here. The next line
// handles this case, and causes any genuine format error to be
// rethrown.
String constant = negative ? ("-" + nm.substring(index))
: nm.substring(index);
result = Integer.valueOf(constant, radix);
}
return result;
}
使用測試如下:
Integer.decode("0xff") // 255
Integer.decode("#ff") // 255
Integer.decode("-07") // -7
Integer.decode("-071") // -57
highestOneBit
該方法返回一個 int 值,該值最多隻有一位,位於指定 int 值中最高位(“最左側”)1 的位置。 如果指定的值在其二進位制補碼錶示中沒有一位,即,如果它等於零,則返回零。
Integer.highestOneBit(44) // 32
44 對應的二進位制為 0010 1100,只選中其最左側的 “1” 那就是 0010 0000,也就是 25 = 32
lowestOneBit
該方法返回一個 int 值,該值最多隻有一位,位於指定 int 值中最低位(“最右側”)1 的位置。 如果指定的值在其二進位制補碼錶示中沒有一位,即,如果它等於零,則返回零。
Integer.lowestOneBit(44) // 4
44 對應的二進位制為 0010 1100,只選中其最右側的 “1” 那就是 0000 0100,也就是 22 = 4
numberOfLeadingZeros
該方法計算首部零的個數。
/**
* 首先在 jvm 中一個 int 型別的資料佔 4 個位元組,共 32 位,其實就相當於一個長度為 32 的陣列。
*
* 那我們要計算首部 0 的個數,就是從左邊第一個位開始累加 0 的個數,直到遇到一個非零值。
*/
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
// 下面的程式碼就是定位從左邊開始第一個非零值的位置,在定位過程中順便累加從左邊開始 0 的個數
// 將 i 無符號右移 16 位後,有二種情況;
// 情況1. i=0,則第一個非零值位於低 16 位,i 至少有 16 個 0,同時將 i 左移 16 位(把低 16 位移到原高 16 位的位置,這樣情況 1 和情況 2 就能統一後續的判斷方式)
// 情況2. i!=0,則第一個非零值位於高 16 位,後續在高 16 位中繼續判斷
// 這個思路就是二分查詢,首先把32位的數分為高低 16 位,如果非零值位於高 16 位,後續再將高 16 位繼續二分為高低 8 位,一直二分到集合中只有 1 個元素
if (i >>> 16 == 0) { n += 16; i <<= 16; }
// 判斷第一個非零值是否位於高 8 位
if (i >>> 24 == 0) { n += 8; i <<= 8; }
// 判斷第一個非零值是否位於高 4 位
if (i >>> 28 == 0) { n += 4; i <<= 4; }
// 判斷第一個非零值是否位於高 2 位
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
測試看看:
Integer.numberOfLeadingZeros(44) // 26
int 4 個位元組,一個位元組八位,所以有 32 位。44 對應完整二進位制就是 0000 0000 0000 0000 0000 0000 0010 1100。所以從左邊開始數起共有 26 個零。
numberOfTrailingZeros
返回指定 int 值的二進位制補碼錶達式中最低位(“最右側”)1 之後的零位數。
Integer.numberOfTrailingZeros(44) // 2
44 對應二進位制 0010 1100。其最右側 “1” 之後的零的個數就是 2。
bitCount
返回指定 int 值的二進位制補碼中 1 的個數。
Integer.bitCount(44) // 3
Integer.bitCount(-44) // 28
44 對應的二進位制補碼為 0000 0000 0000 0000 0000 0000 0010 1100。1 有 3 個。
-44 對應的二進位制補碼為 1111 1111 1111 1111 1111 1111 1101 0100。1 有 28 個。
End.
相關文章
- 一些實用但不為人知的Unix命令
- 專案中常用到的一些方法整理
- js 一些專案中常用的原型方法整理JS原型
- 一些不常用的工具整理
- Java中Integer類的基本方法Java
- 走進 JDK 之 IntegerJDK
- 原生js的常用方法整理JS
- 整理Object的一些方法Object
- 常用JS方法整理JS
- js常用方法整理JS
- java Integer中的方法解析(位操作)Java
- 整理的一些常用到的 Nginx 配置Nginx
- JS-實用方法整理JS
- 一些常用&實用的Linux命令Linux
- 整理的一些常用系統表 (轉)
- MySQL的一些常用的SQL語句整理MySql
- Linux中的一些常用操作方法(轉)Linux
- 從JDK原始碼角度看IntegerJDK原始碼
- JDK原始碼閱讀-Integer類JDK原始碼
- JDK原始碼中的一些“小技巧”JDK原始碼
- Linux常用命令整理,簡單實用!Linux
- 整理debian安裝過程中的一些問題與方法
- 字串和陣列常用方法整理字串陣列
- gookit/goutil - Go一些常用的工具函式實現、增強、收集和整理Go函式
- iOS一些自己常用的工具方法iOS
- 類的一些常用魔術方法
- JDK 原始碼 Integer解讀之三(valueOf)JDK原始碼
- JDK 原始碼 Integer解讀之一(parseInt)JDK原始碼
- JavaScript關於陣列的一些方法整理JavaScript陣列
- js中的常用方法JS
- linux中升級jdk的方法LinuxJDK
- java 常用工具類 方法整理Java
- Java常用工具類方法整理Java
- panda dataframe的一些常用操作方法
- js中修改this的指向方法整理JS
- linux中的一些常用指令Linux
- tk.mybatis中常用方法的使用(最實用)MyBatis
- X5.3中常用到的jQuery整理jQuery