您的位置:首页 > 编程语言 > Java开发

将一个整形数转换成字符串形式

2013-09-05 21:57 225 查看
假如给你一个题目,将一个整型数转换成它的字符串形式,你会怎么做,你会这样做,new Integer(432).toString(),或者Integer.toString(432),再或者Integer.toString(432,10)这几个方法都能办到,但是他们是怎么实现的呢,假如让你去实现你怎么做呢,我们通常的做法是:

public static String convertIntToString(int i){
int j = 0; //用来表示表示i中每一位上的数字
int size = 0; //用来表示i的位数
size = (i < 0) ? sizeOfInt(-i) + 1:sizeOfInt(i);
char[] buf = new char[size];

if(i < 0){
i = -i;
buf[0] = '-';
}

while(i != 0){
j = i % 10;
i = i / 10;
buf[--size] = Digit[j];
}

return new String(buf);
}

public static int sizeOfInt(int x){
int i = 0;
while(x != 0){
x /= 10;
i++;
}
return i;
}

public static char[] Digit = {
'0','1','2','3','4','5','6','7','8','9'
};

converIntToString()方法可以将任意的整形数转换成它的字符串形势,但是java库函数中是怎么实现的呢?在Integer类中的有个方法toString(int i)将整型转换成字符串表示,这个实现方法对渗透了对性能的考虑,对实际情况的考虑,让我们学习一下java源码。

/**
*将i转换成其字符串形式
*/
public static String toString(int i) {
////如果i是int的最小值,直接返回一个常数,不用进行计算,
//不知道为什么没有对int的最大值进行优化,可能会在其他地方已经优化了,
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);  //利用size方法计算i的位数
char[] buf = new char[size];
getChars(i, size, buf);  //这一步才将i的值转换成字符数组,使用了getChars方法,这个方法也很与众不同啊
return new String(buf, true);
}

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;
}

/**
* Places characters representing the integer i into the
* character array buf. The characters are placed into
* the buffer backwards starting with the least significant
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Integer.MIN_VALUE
*/
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的值大于65536就执行这个循环,一次能产生两个字符哦
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
//用移位操作比直接的乘法操作要快,以后咱们自己写程序,能不能从运用大师们的这一招呢?
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
//这两个数组设计的比较精巧,
//DigitOne中根据数组下表能取出各位数的字符表示,
//DigitTens取出十位上数的字符表示
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}

// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
//这一步牛b吧完成的是i/10操作,>>>这个操作符的意思是向右移位之后用0填充最高位。
//但是这一步还是没有看懂到底是怎样移位的,求高手赐教
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}

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'
};

通过阅读java源码,我们能从中学到这样几点:

 1.尽可能的用移位操作代替乘除法

 2.有时候查表操作比直接运算性能要好

 3.考虑问题要全面,不要写一些教学用的代码片段,要充分考虑问题的情况,

   比如这里面就充分考虑了,整型数如果大于65536怎么操作,小于65536又怎么操作,

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐