一、常见方法
1、public static String toString(int i)
返回一个表示指定整数的 String 对象。将该参数转换为有符号的十进制表示形式,以字符串形式返回它,就好像将参数和基数 10 作为参数赋予 toString(int, int) 方法。 参数: i – 要转换的整数。 返回: 十进制(基数 10)参数的字符串表示形式。 源码:
======================Integer.class============================ @HotSpotIntrinsicCandidate public static String toString(int i) { // 数字长度 int size = stringSize(i); // 紧凑的空间布局(COMPACT_STRINGS),LATIN1单字节编码,UTF16双字节编码 if (COMPACT_STRINGS) { byte[] buf = new byte[size]; // 单字节编码,一个字节存储一个数字 getChars(i, size, buf); return new String(buf, LATIN1); } else { byte[] buf = new byte[size * 2]; // 双字节编码,两个字节存储一个数字 StringUTF16.getChars(i, size, buf); return new String(buf, UTF16); } } ==================Integer.class======================= // int类型数字位数 // int类型范围[-2147483648, 2147483647] // 最高10位数。 // 正数长度最高是10,负数长度最高是11(比正数多一位负号) static int stringSize(int x) { int d = 1; if (x >= 0) { d = 0; x = -x; } int p = -10; for (int i = 1; i < 10; i++) { if (x > p) return i + d; p = 10 * p; } return 10 + d; } ================Integer.class======================== static int getChars(int i, int index, byte[] buf) { int q, r; int charPos = index; boolean negative = i < 0; // 转为负数参加下面的计算 if (!negative) { i = -i; } // Generate two digits per iteration // 每次迭代生成两位数,并通过两个字符数组DigitOnes、DigitTens获取十位数和个位数所对应的字符。 // 从后到前填充buf。 while (i <= -100) { q = i / 100; // 取出该数字的最低两位 r = (q * 100) - i; i = q; // 个位对应的字符 buf[--charPos] = DigitOnes[r]; // 十位对应的字符 buf[--charPos] = DigitTens[r]; } // We know there are at most two digits left at this point. // 经过前面的迭代后,0 > i > -100, q = i / 10; // 取数字i的个位(i可能是两位数或个位数) r = (q * 10) - i; // 通过偏移量r取数字r对应的字符'r' buf[--charPos] = (byte)('0' + r); // Whatever left is the remaining digit. // 如果前面的i是两位数,则q是i的十位数,且q<0 // 如果前面的i是一位数,则q==0,q为0则不用将q放入buf if (q < 0) { buf[--charPos] = (byte)('0' - q); //q为负数,计算绝对值|q|对应的'q'时用'0'-q。 } // 若是负数,加上负号 if (negative) { buf[--charPos] = (byte)'-'; } return charPos; } ======================StringUTF16.class======================================= static int getChars(int i, int index, byte[] buf) { int q, r; int charPos = index; boolean negative = (i < 0); if (!negative) { i = -i; } // Get 2 digits/iteration using ints while (i <= -100) { q = i / 100; r = (q * 100) - i; i = q; putChar(buf, --charPos, Integer.DigitOnes[r]); putChar(buf, --charPos, Integer.DigitTens[r]); } // We know there are at most two digits left at this point. q = i / 10; r = (q * 10) - i; putChar(buf, --charPos, '0' + r); // Whatever left is the remaining digit. if (q < 0) { putChar(buf, --charPos, '0' - q); } if (negative) { putChar(buf, --charPos, '-'); } return charPos; } ========================StringUTF16.class============================= @HotSpotIntrinsicCandidate // intrinsic performs no bounds checks static void putChar(byte[] val, int index, int c) { assert index >= 0 && index < length(val) : "Trusted caller missed bounds check"; index <<= 1; // 和 index*2 等价,用来确定c在val中存储的起始位置,字节长度是数字字符串长度的两倍 // val中两个字节存储c(00000000 xxxxxxxx)。 // UTF-16中有字节序的概念,存储的时候,要区分子节序,即大小端 // HI_BYTE_SHIFT和LO_BYTE_SHIFT其中一个是8,一个是0 // 取c的高8位或低8位存储在val的低地址或高地址,达到大小端存储的目的。 val[index++] = (byte)(c >> HI_BYTE_SHIFT); val[index] = (byte)(c >> LO_BYTE_SHIFT); } ======================StringUTF16.class 大小端(字节序)============================================== private static native boolean isBigEndian(); // 大端 static final int HI_BYTE_SHIFT; static final int LO_BYTE_SHIFT; static { if (isBigEndian()) { HI_BYTE_SHIFT = 8; LO_BYTE_SHIFT = 0; } else { HI_BYTE_SHIFT = 0; LO_BYTE_SHIFT = 8; } } ==============Integer.class=============================== // 获取两位数10*a+b其十位(a)、个位(b)对应的字符'a'、'b'。 // 如下获取十位所对应的字符: // byte i = (byte)10*a+b; // a,b属于10以内的数 // DigitTens[i] == a;// true static final byte[] 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', } ; static final byte[] 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', } ;
2、public static String toString(int i,int radix)
- 返回用第二个参数指定基数表示的第一个参数的字符串表示形式。
源码:
==========================Integer.class========================================= public static final int MIN_RADIX = 2; public static final int MAX_RADIX = 36; public static String toString(int i, int radix) { // 只支持2-36进制,范围之外的指定为10进制 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ // 十进制则直接调用public static String toString(int i)方法 if (radix == 10) { return toString(i); } // 单字节Latin1编码 if (COMPACT_STRINGS) { // 将int型数据转为其他进制(2-36),只有2进制的结果其长度才最大 // Integer.MIN_VALUE == -2147483648,2进制为-10000000000000000000000000000000,2进制长度为33 // Integer.MAX_VALUE == 2147483647,2进制为1111111111111111111111111111111,2进制长度为31 // 所以33个长度的buf数组足够。 byte[] buf = new byte[33]; // 是否为负数 boolean negative = (i < 0); int charPos = 32; // 正数转为负数 if (!negative) { i = -i; } // 十进制i转为其他进制 while (i <= -radix) { buf[charPos--] = (byte)digits[-(i % radix)]; i = i / radix; } buf[charPos] = (byte)digits[-i]; // 负数则再加上负号 if (negative) { buf[--charPos] = '-'; } return StringLatin1.newString(buf, charPos, (33 - charPos)); } // UTF-16编码 return toStringUTF16(i, radix); } ====================================Integer.class============================================ // 2-36进制所用到的字符 static final 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' }; ==================================StringLatin1.class========================================== // Latin1编码 public static String newString(byte[] val, int index, int len) { return new String(Arrays.copyOfRange(val, index, index + len), LATIN1); } String(byte[] value, byte coder) { this.value = value; this.coder = coder; } ====================================Arrays.class============================================== // 复制一份 public static byte[] copyOfRange(byte[] original, int from, int to) { int newLength = to - from; if (newLength < 0) throw new IllegalArgumentException(from + " > " + to); byte[] copy = new byte[newLength]; System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength)); return copy; } ==================================Integer.class=========================================== // UTF-16编码 private static String toStringUTF16(int i, int radix) { // 两倍字节存储 byte[] buf = new byte[33 * 2]; boolean negative = (i < 0); int charPos = 32; if (!negative) { i = -i; } // StringUTF16.putChar方法和前面一样。 while (i <= -radix) { StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]); i = i / radix; } StringUTF16.putChar(buf, charPos, digits[-i]); if (negative) { StringUTF16.putChar(buf, --charPos, '-'); } return StringUTF16.newString(buf, charPos, (33 - charPos)); } =============================StringUTF16.class========================================== public static String newString(byte[] val, int index, int len) { // 上面已经判断过COMPACT_STRINGS,所以此处不会进入if分支 if (String.COMPACT_STRINGS) { byte[] buf = compress(val, index, len); if (buf != null) { return new String(buf, LATIN1); } } int last = index + len; // 单个字符占两字节,所以last乘2(last<<1) return new String(Arrays.copyOfRange(val, index << 1, last << 1), UTF16); }
3、public static int bitCount(int i) 返回指定 int 值的二进制补码表示形式的 1 位的数量。
源码:
1 @HotSpotIntrinsicCandidate 2 public static int bitCount(int i) { 3 // HD, Figure 5-2 4 i = i - ((i >>> 1) & 0x55555555); 5 i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); 6 i = (i + (i >>> 4)) & 0x0f0f0f0f; 7 i = i + (i >>> 8); 8 i = i + (i >>> 16); 9 return i & 0x3f; 10 }
使用:
4、public static int parseInt(String s,int radix) throws NumberFormatException
使用第二个参数指定的基数,将字符串参数解析为有符号的整数。除了第一个字符可以是用来表示负值的 ASCII 减号 '-'
( '\u002D’
)外,字符串中的字符必须都是指定基数的数字(通过 Character.digit(char, int)
是否返回一个负值确定)。返回得到的整数值。
- 源码:
public static int parseInt(String s, int radix) throws NumberFormatException { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */ // 字符串s不能为null if (s == null) { throw new NumberFormatException("null"); } // 进制不能小于2 if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } // 进制不能大于36 if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } boolean negative = false; int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; if (len > 0) { char firstChar = s.charAt(0); // 若首字符ASCII值小于字符'0', 则可能是正负号 if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { // 负号 negative = true; limit = Integer.MIN_VALUE; // 负数最小值 } else if (firstChar != '+') { // 不是负号又不是正号,则非法,报错 throw NumberFormatException.forInputString(s); } // 字符串不能只有正负号 if (len == 1) { // Cannot have lone "+" or "-" throw NumberFormatException.forInputString(s); } i++; // 下标移动到第二个字符 } int multmin = limit / radix; // ?????????????? int result = 0; // 计算该radix进制字符串对应的10进制 // 二进制11010计算十进制: // 第一种:1*2^4 + 1*2^3 + 0*2^2 + 1*2^1 + 0*2^0 // 第二种:((((1*2+1)+0)*2+1)*2+0)*2 // 下面计算10进制用的是第二种。 while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE // 字符对应的十进制数,'0'=>0, '1'=>1, 'a'=>10, 'A'=>10 int digit = Character.digit(s.charAt(i++), radix); if (digit < 0 || result < multmin) { // ?????????????? throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { // ?????????????? throw NumberFormatException.forInputString(s); } result -= digit; } return negative ? result : -result; } else { throw NumberFormatException.forInputString(s); } }
5、
public static Integer decode(String nm)
throws NumberFormatException
将 String
解码为 Integer
。接受通过以下语法给出的十进制、十六进制和八进制数字
源码:
// 8进制:0开头 // 16进制:0x、0x、#开头 // 10进制:104 // 负数首位加负号(-) public static Integer decode(String nm) throws NumberFormatException { // 默认10进制 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 // 以 0x 或 0X开头则是16进制 if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) { index += 2; radix = 16; } // 以"#"开头的也是16进制 else if (nm.startsWith("#", index)) { index ++; radix = 16; } // 不是16进制,而且以0开头,且0之后还有字符,则是8进制 else if (nm.startsWith("0", index) && nm.length() > 1 + index) { index ++; radix = 8; } // 正负号没有在首位,报错 if (nm.startsWith("-", index) || nm.startsWith("+", index)) throw new NumberFormatException("Sign character in wrong position"); try { // 最终实现在Integer.parseInt方法 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; }