public final class Integer extends Number implements Comparable<Integer>
private final int value;// fianl private static final long serialVersionUID = 1360826667806852920L; // 值爲 (-(2的31次方)) 的常量,它表示 int 類型可以表示的最小值。 public static final int MIN_VALUE = 0x80000000; // 值爲 ((2的31次方)-1) 的常量,它表示 int 類型可以表示的最大值。 public static final int MAX_VALUE = 0x7fffffff; // 表示基本類型 int 的 Class 實例。 public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); // 用來以二進制補碼形式表示 int 值的比特位數。 public static final int SIZE = 32; // 用來以二進制補碼形式表示 int 值的字節數。1.8之後纔有 public static final int BYTES = SIZE / Byte.SIZE; // 用來取兩位數的十位數字 final static char [] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; // 用來取兩位數的個位數字 final static char [] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; // 用來取不一樣進制的某一位數字 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' }; // 用來肯定十進制位數 final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE };
private final int value;
java
// value是final的 Integer i = new Integer(10); i = 5; // 反編譯以後 Integer i = new Integer(10); i = Integer.valueOf(5);
// 兩個構造方法 初始化一個Integer對象的時候只能建立一個十進制的整數 public Integer(int value) { this.value = value; } public Integer(String s) throws NumberFormatException { this.value = parseInt(s, 10);
Integer.valueof()git
/** * 1.Integer類加載時,初始化一個-128到127的數組緩存 * 2.調用valueOf(int i)時,IntegerCache.cache中有直接取,IntegerCache.cache中沒有須要new Integer * 3.建立Integer時,Integer i = 5(編譯後Integer i = Integer.valueOf(5));或者直接用Integer.valueOf(5) * 4.-Djava.lang.Integer.IntegerCache.high=xxx就能夠改變緩存值的最大值 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); } public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); } private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
String--->Integer數組
Integer getInteger(String nm) Integer getInteger(String nm, int val) Integer getInteger(String nm, Integer val) Integer decode(String nm) Integer valueOf(String s) Integer valueOf(String s, int radix) int parseUnsignedInt(String s) int parseUnsignedInt(String s, int radix) int parseInt(String s) int parseInt(String s, int radix) // 調用棧 getInteger(String nm) ---> getInteger(nm, null);--->Integer.decode()--->Integer.valueOf()--->parseInt() // parseInt()主要代碼 while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++),radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; } // 思路:357 = 3*10^2+5*10^1+7*10^0 = ((3*10+5)*10+7); // 用負數計算緣由:用正數計算表示不了Integer.MIN_VALUE = 0x80000000;
Integer--->String緩存
String toString() static String toString(int i) static String toString(int i, int radix) static String toBinaryString(int i) static String toHexString(int i) static String toOctalString(int i) static String toUnsignedString(int i) static String toUnsignedString(int i, int radix) public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-2147483648"; int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);// 計算字符數(根據sizeTable屬性) char[] buf = new char[size]; getChars(i, size, buf);// int-->char數組 return new String(buf, true); } /** * 計算字符數(根據sizeTable屬性) * 1.局部性原理之空間局部性:sizeTable爲數組,存儲在相鄰的位置,cpu一次加載一個塊數據數據到cache中(多個數組數據),此後訪問sizeTable 不須要訪問內存 * 2.基於範圍的查找,是很實用的設計技術 */ final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; static int stringSize(int x) { for (int i=0; ; i++) if (x <= sizeTable[i]) return i+1; } /** * int-->char數組 * 1.取餘的思想 * 2.移位和加法的效率比直接乘除的效率要高,乘法的效率比除法的效率要高 * 3.分while for兩段循環緣由:大於65536的數乘52429超過int最大值,溢出 * 4.選52429緣由:保證(i * num2) >>> (num3)結果接近於0.1,52429/2^19精度小 * 5.選65536緣由:①65536=2^16 2^16 * 52429 < 2^32 < 2^17 * 52429 * ②q = (i * 52429) >>> (16+3); >>>無視符號位補0 --> i*52429只要小於2^32次方便可 * 6.r = i - ((q << 3) + (q << 1)); 移位和加法代替乘法 * q = (i * 52429) >>> (16+3); 移位和乘法代替除法 * buf [--charPos] = DigitOnes[r]; 直接取十位數字,代替再除一次取餘 */ static void getChars(int i, int index, char[] buf) { int q, r; int charPos = index; char sign = 0; if (i < 0) { sign = '-'; i = -i; } // 每次循環事後,都會將i中的走後兩位保存到字符數組buf中的最後兩位中,讀者能夠將數字i設置爲12345678測試一下, // 第一次循環結束以後,buf[7] = 8,buf[6]=7。第二次循環結束以後,buf[5] = 6,buf[4] = 5。 while (i >= 65536) { q = i / 100; r = i - ((q << 6) + (q << 5) + (q << 2));// really: r = i - (q * 100); i = q; buf [--charPos] = DigitOnes[r];// 取DigitOnes[r]的目的其實取數字r%10的結果 buf [--charPos] = DigitTens[r];// 取DigitTens[r]的目的實際上是取數字r/10的結果 } // 循環將其餘數字存入字符數組中空餘位置 for (;;) { q = (i * 52429) >>> (16+3);// 這裏其實就是除以10。取數52429和16+3的緣由在後文分析。 r = i - ((q << 3) + (q << 1));// r = i-(q*10) ... // 將數字i的最後一位存入字符數組, // 仍是12345678那個例子,這個for循環第一次結束後,buf[3]=4。 buf [--charPos] = digits [r]; i = q; // for循環結束後,buf內容爲「12345678」; if (i == 0) break; } if (sign != 0) { buf [--charPos] = sign; } }
Integer s = new Integer(5); System.out.println(s + ""); // 反編譯: Integer s = new Integer(5); System.out.println((new StringBuilder()).append(s).append("").toString());
// 無符號轉換 public static long toUnsignedLong(int x) { return ((long) x) & 0xffffffffL; } /** * 該方法主要用於計算二進制數中1的個數。 * 0x55555555等於01010101010101010101010101010101,0x33333333等於110011001100110011001100110011,0x0f0f0f0f等於1111000011110000111100001111。 * 它的核心思想就是先每兩位一組統計看有多少個1,好比10011111則每兩位有一、一、二、2個1,記爲01011010,而後再算每四位一組看有多少個1,而01011010則每四位有二、4個1,記爲00100100,接着每8位一組就爲00000110,接着16位,32位 * 最終在與0x3f進行與運算,獲得的數即爲1的個數。 */ public static int bitCount(int i) { i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; } /** * 該方法返回i的二進制中最高位的1,其餘全爲0的值。 * 好比i=10時,二進制即爲1010,最高位的1,其餘爲0,則是1000。若是i=0,則返回0。若是i爲負數則固定返回-2147483648,由於負數的最高位必定是1,即有1000,0000,0000,0000,0000,0000,0000,0000。 * 將i右移一位再或操做,則最高位1的右邊也爲1了,接着再右移兩位並或操做,則右邊1+2=3位都爲1了,接着1+2+4=7位都爲1,直到1+2+4+8+16=31都爲1,最後用i - (i >>> 1)天然獲得最終結果。 */ public static int highestOneBit(int i) { i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); } /** * 獲取最低位1,其餘全爲0的值。 * 先取負數,這個過程須要對正數的i取反碼而後再加1,獲得的結果和i進行與操做,恰好就是最低位1其餘爲0的值了 */ public static int lowestOneBit(int i) { return i & -i; } /** * 該方法返回i的二進制從頭開始有多少個0。i爲0的話則有32個0。 * 這裏處理實際上是體現了二分查找思想的,先看高16位是否爲0,是的話則至少有16個0,不然左移16位繼續往下判斷,接着右移24位看是否是爲0,是的話則至少有16+8=24個0,直到最後獲得結果。 */ public static int numberOfLeadingZeros(int i) { if (i == 0) return 32; int n = 1; if (i >>> 16 == 0) { n += 16; i <<= 16; } if (i >>> 24 == 0) { n += 8; i <<= 8; } if (i >>> 28 == 0) { n += 4; i <<= 4; } if (i >>> 30 == 0) { n += 2; i <<= 2; } n -= i >>> 31; return n; } /** * 該方法返回i的二進制從尾開始有多少個0。它的思想和前面的相似,也是基於二分查找思想,詳細步驟再也不贅述。 */ public static int numberOfTrailingZeros(int i) { int y; if (i == 0) return 32; int n = 31; y = i <<16; if (y != 0) { n = n -16; i = y; } y = i << 8; if (y != 0) { n = n - 8; i = y; } y = i << 4; if (y != 0) { n = n - 4; i = y; } y = i << 2; if (y != 0) { n = n - 2; i = y; } return n - ((i << 1) >>> 31); } /** * 該方法便是將i進行反轉,反轉就是第1位與第32位對調,第二位與第31位對調,以此類推。 * 它的核心思想是先將相鄰兩位進行對換,好比10100111對換01011011,接着再將相鄰四位進行對換,對換後爲10101101,接着將相鄰八位進行對換,最後把32位中中間的16位對換,而後最高8位再和最低8位對換。 */ public static int reverse(int i) { i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333; i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f; i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24); return i; }
二、Java源碼 Integer.bitCount實現過程學習
四、從JDK源碼角度看Integerui
五、Integer源碼詳解this