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