整形转换为字符串,写了五种算法,并进行了性能分析:
1. 算法: 直接先求得长度,然后从左向右求得各位的大小
private static class Int2String1 implements Int2String { public String int2String(int intValue) { if (intValue == 0) { return "0"; } int length = 0; boolean sign = false; if (intValue < 0) { intValue = -intValue; sign = true; length++; } int k = 1; while (true) { if (intValue >= k) { length++; k = k * 10; } else { break; } } char[] holder = new char[length]; int start = 0; if (sign) { holder[0] = '-'; start = 1; } for (; start < length; ++start) { int count = (length - start - 1); int pow10 = 1; for (int i = 0; i < count; i++) { pow10 = pow10 * 10; } holder[start] = (char) ((intValue / Math.pow(10, count)) + '0'); intValue = intValue % pow10; } return new String(holder); } }
打印时间:
1the time is 12122, strValue = -100121312
2. 算法: 直接从右向左, 或者说低位到高位进行逐个插入。最后插入符号位
private static class Int2String2 implements Int2String { public String int2String(int intValue) { char[] str = new char[0]; boolean sign = false; if (intValue == 0) { return "0"; } if (intValue < 0) { sign = true; intValue = -intValue; } while (true) { int leftValue = intValue % 10; char additionalChar = (char) (leftValue + '0'); char[] old = str; str = new char[str.length + 1]; str[0] = additionalChar; for (int i = 1; i < str.length; ++i) { str[i] = old[i - 1]; } intValue = intValue / 10; if (intValue == 0) { break; } } if (sign) { char[] old = str; str = new char[str.length + 1]; str[0] = '-'; for (int i = 1; i < str.length; ++i) { str[i] = old[i - 1]; } } return new String(str); } }
打印时间:
1the time is 3426, strValue = -100121312
3.算法:先斤算长度,计算长度时与10的倍数比较。再从右向左进行运算各位的值。
private static class Int2String3 implements Int2String { public String int2String(int intValue) { if (intValue == 0) { return "0"; } int length = 0; boolean sign = false; if (intValue < 0) { intValue = -intValue; sign = true; length++; } int k = 1; while (true) { if (intValue >= k) { length++; k = k * 10; } else { break; } } char[] holder = new char[length]; int start = 0; if (sign) { holder[0] = '-'; start = 1; } for (int i = length - 1; i >= start; --i) { holder[i] = (char) ((intValue % 10) + '0'); intValue = intValue / 10; } return new String(holder); } }
打印时间:
1the time is 834, strValue = -100121312
4. 先斤算长度,再从右向左进行运算各位的值。计算长度采用除法求模。
private static class Int2String4 implements Int2String { public String int2String(int intValue) { int length = 0; boolean sign = false; if (intValue < 0) { sign = true; intValue = -intValue; } int k = intValue; while (k >= 0) { length++; k = k / 10; if (k == 0) { break; } } char[] charArray; if (sign) { length = length + 1; charArray = new char[length]; charArray[0] = '-'; } else { charArray = new char[length]; } int m = intValue; int index = length - 1; while (true) { int leftValue = m % 10; charArray[index] = (char) (leftValue + '0'); index--; m = m / 10; if (m == 0) { break; } } return new String(charArray); } }
打印时间:
1the time is 1102, strValue = -100121312
5. 不再计算长度,而是采用一个buffer。最后构造字符串直接使用此buffer构造。由于10进制的位数一定是小于8进制的位数。32位int转换到8进制就是11位,推断10进制的最大位数也是11位。
private static class Int2String5 implements Int2String { public String int2String(int intValue) { int position = 10; char[] buf = new char[11]; if (intValue < 0) { intValue = -intValue; buf[0] = '-'; } while (true) { int leftValue = intValue % 10; buf[position] = (char) (leftValue + '0'); intValue = intValue / 10; if (intValue == 0) { break; } else { position--; } } return new String(buf, position, buf.length - position); } }
打印时间:
1the time is 742, strValue = 100121312
6. 采用系统自带的算法
private static class Int2String6 implements Int2String { public String int2String(int intValue) { return String.valueOf(intValue); } }
打印时间:
1the time is 764, strValue = -100121312
由此可见java SDK 提供的算法并不是最优算法。采用buffer避免计算长度的算法速度更快。可以在系统内存要求不高的时候直接提供一个公用的11位的buffer去做转换可能比java系统自带的算法更快。
于是得到了以下算法
public static char[] buf = new char[11]; private static class Int2String7 implements Int2String { public String int2String(int intValue) { int position = 10; if (intValue < 0) { intValue = -intValue; buf[0] = '-'; } while (true) { int leftValue = intValue % 10; buf[position] = (char) (leftValue + '0'); intValue = intValue / 10; if (intValue == 0) { break; } else { position--; } } return new String(buf, position, buf.length - position); } }
打印:
1the time is 636, strValue = 100121312
可是此算法有个很大的问题,就是在多线程环境下的同步问题,于是解决同步问题,于是有了算法7.
7. 在6的基础上解决同步问题:
public static char[] buf = new char[11]; private static class Int2String7 implements Int2String { public synchronized String int2String(int intValue) { int position = 10; if (intValue < 0) { intValue = -intValue; buf[0] = '-'; } while (true) { int leftValue = intValue % 10; buf[position] = (char) (leftValue + '0'); intValue = (intValue >>1)/5; if (intValue == 0) { break; } else { position--; } } return new String(buf, position, buf.length - position); } }
打印:
1the time is 616, strValue = 100121312
总结 :
整形转字符串,减少循环次数可以很明显提升运算速度。乘法运算比除法运算效率更高。尽量使用乘法代替除法。