在看HashMap源碼的是否發現了一個很好玩的方法:
java.util.HashMap.tableSizeFor ;如題,求最近的2的次方值
一下爲對這個方法的具體分析和註釋:
/**
* int類型,2的最大整數次方(2的30次方)值
*/
public static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 根據一個整數n,取到 最近的、大於等於n的 2的整數次方;<br>
* 例如:n<0,返回1<br>
* n=0, 返回1;<br>
* n=1 返回1;<br>
* n=3返回4<br>
* ...<br>
* int型數據最大的的2的整數次方爲2的30次方,則結果的返回值最大爲2的30次方<br>
*
* ;實現原理:<br>
* 00000000,00000000,00000000,10000001;傳入參數n,(129)則n的二進制表示裏,從左到右至少能遇到一個1:<br>
* 00000000,00000000,00000000,10000000;要求傳入128返回128,無這一步會導致返回256<br>
* 00000000,00000000,00000000,11000000;n|=n>>>1將n右移1位,然後與n按位或,則至少左到右至少能遇到2個1;<br>
* 00000000,00000000,00000000,11110000;n|=n>>>2將n右移2位,然後與n按位或,則至少左到右至少能遇到4個1;<br>
* 00000000,00000000,00000000,11111111;n|=n>>>4將n右移4位,然後與n按位或,則至少左到右至少能遇到8個1;<br>
* 00000000,00000000,00000000,11111111;n|=n>>>4將n右移8位,然後與n按位或,則至少左到右至少能遇到16個1;沒有達到,說明結果沒有這麼多位<br>
* 00000000,00000000,00000000,11111111;n|=n>>>4將n右移16位,然後與n按位或,則至少左到右至少能遇到32個1;沒有達到,說明結果沒有這麼多位<br>
* 00000000,00000000,00000001,00000000;n=n+1,將n+1,即得到我們需要的結果
*
* @param n
*
*/
public static final int tableSizeFor(int n) {
System.out.println("n :" + Integer.toBinaryString(n));
n = n - 1;
System.out.println("n-1 :" + Integer.toBinaryString(n));
n |= n >>> 1;
System.out.println("n>>>1 :" + Integer.toBinaryString(n));
n |= n >>> 2;
System.out.println("n>>>2 :" + Integer.toBinaryString(n));
n |= n >>> 4;
System.out.println("n>>>4 :" + Integer.toBinaryString(n));
n |= n >>> 8;
System.out.println("n>>>8 :" + Integer.toBinaryString(n));
n |= n >>> 16;
System.out.println("n>>>16:" + Integer.toBinaryString(n));
n = (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
System.out.println("n :" + Integer.toBinaryString(n));
System.out.println(n);
return n;
}