开发实战细节之——关于整型转换为字符串类型的性能与实现分析

细节决定成败,开发中往往从一些细节就可以看出一个程序员的开发水准,下面我就给大家分享一下开发中最最常见的int转换为String类型的方法及其性能解析。

一般大家最常用的方法有

方法一:String s1 = String.valueOf(i);

方法二:String s2 = i+"";  

不知道有没有人用这种方法呢?

方法三:String s3 = Integer.toString(i);

继续往下看之前,大家先猜测一下这三种方法哪种方法的效率最高,耗时最短,且不耗内存?相信结果会令你大吃一惊!

话不多说,直接上代码,用事实说话。

 1 public static void main(String[] args) {
 2         long t = System.currentTimeMillis();
 3         for (int i = 0; i < 100000; i++) {
 4             String s0 = String.valueOf(i);
 5         }
 6         System.out.println("耗时" + (System.currentTimeMillis() - t));
 7
 8         t = System.currentTimeMillis();
 9         for (int i = 0; i < 100000; i++) {
10             String s = "" + i;
11         }
12         System.out.println("耗时" + (System.currentTimeMillis() - t));
13
14         t = System.currentTimeMillis();
15         for (int i = 0; i < 100000; i++) {
16             String s = Integer.toString(i);
17         }
18         System.out.println("耗时" + (System.currentTimeMillis() - t));
19     }

运行结果如下:

结果是不是大跌眼镜啊?没想到我们最常用的i+""的性能竟然如此之差!而性能最好的竟然是没人怎么用的toString(i);为什么会这样呢?经过堆栈分析发现:

String.valueOf(i)的方法调用的竟然时第三种方法:Integer.toString(i),多此调试后发现他们的耗时比基本保持在20:8,那么toString(i)的内部又是怎样实现的呢?

下面是Integer.toString(i)的实现代码:

1 public static String toString(int i) {
2                 if (i == Integer.MIN_VALUE)
3                     return "-2147483648";
4                 int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
5                 char[] buf = new char[size];
6                 getChars(i, size, buf);
7                 return new String(buf, true);
8             }

其中stringSize(i)又做了什么事呢?经过进一步跟踪发现

1  static int stringSize(int x) {
2                 for (int i=0; ; i++)
3                     if (x <= sizeTable[i])
4                     return i+1;
5               }

而sizeTable[]又是一个怎样的数组呢?继续往下看,

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

原来在调用toString(i)的时候,如果会判断i是否是负数,如果是负数就将其求反为正数,然后会根据 sizeTable数组来 判断 i 的位数并返回创建一个比i的长度+1的字符数组,比如i=11,那么size就是3,然后就会创建一个3位的字符数组。那么问题来了,getChars()有是干什么的呢?

 1  /**
 2      * Places characters representing the integer i into the
 3      * character array buf. The characters are placed into
 4      * the buffer backwards starting with the least significant
 5      * digit at the specified index (exclusive), and working
 6      * backwards from there.
 7      *
 8      * Will fail if i == Integer.MIN_VALUE
 9      */
10     static void getChars(int i, int index, char[] buf) {
11         int q, r;
12         int charPos = index;
13         char sign = 0;
14
15         if (i < 0) {
16             sign = ‘-‘;
17             i = -i;
18         }
19
20         // Generate two digits per iteration
21         while (i >= 65536) {
22             q = i / 100;
23         // really: r = i - (q * 100);
24             r = i - ((q << 6) + (q << 5) + (q << 2));
25             i = q;
26             buf [--charPos] = DigitOnes[r];
27             buf [--charPos] = DigitTens[r];
28         }
29
30         // Fall thru to fast mode for smaller numbers
31         // assert(i <= 65536, i);
32         for (;;) {
33             q = (i * 52429) >>> (16+3);
34             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
35             buf [--charPos] = digits [r];
36             i = q;
37             if (i == 0) break;
38         }
39         if (sign != 0) {
40             buf [--charPos] = sign;
41         }
42     }

仔细分析代码发现,这个函数的功能就是将int型的i从右向左(即从个位数开始)填充到字符数组buf中。至此方法一String.valueOf(i)和方法三Integer.toString(i)分析完毕。

那么方法二是本人最最不推荐,最耗时的方法,之所以写这篇文章是因为我在看一段视频的时候以为老师说他以前刚入职的时候就是用这种方法从而项目中出现大量的+"",结果是被项目经理批评了一顿。所以小伙伴们,如果你还在用方法二就赶快更正过来吧!

那么方法二为什么会这么耗时呢?

因为没+""一次,就会调用一次

public StringBuffer() {
  super(16);
}

方法,这就意味着没+""一次,就会在内存中实例化一个StringBuffer()对象,如果一个项目中大量使用该方法,不耗时耗内存才怪呢。

个人总结:int类型转为String类型时推荐使用Integer.toString(i)或String.valueOf(i)方法。尽管我现在也是很不习惯,但现在慢慢的改变还为时不晚。希望小伙伴们也能早日养成好的编程习惯!如果有哪个地方我分析的不对或者有什么更好的建议或更实用的细节还请小伙伴们不吝赐教啊!

时间: 2024-10-23 01:59:46

开发实战细节之——关于整型转换为字符串类型的性能与实现分析的相关文章

JAVA 长整型转换为IP地址的方法

代码如下: /** * 整型解析为IP地址 * @param num * @return */ public static String int2iP(Long num) { String str = null; Long[] tt = new Long[4]; tt[0] = (num >>> 24) >>> 0; tt[1] = ((num << 8) >>> 24) >>> 0; tt[2] = (num <&

(转)JAVA的整型与字符串相互转换

JAVA的整型与字符串相互转换1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或         i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 Str

JAVA的整型与字符串相互转换

JAVA的整型与字符串相互转换 1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 String ? A

stringsteam使用之整型转字符串

最近需要用到整型转字符串的操作,学习了stringstream一些皮毛. 首先需要包含头文件. #include<sstream> 然后用流操作的方式将值传递给stringstream对象ss.而ss.str()即为转换的字符串. stringstream ss; if (n < 1) return ret; for (int i = 1; i <= n;i++) { ss << i; if (i%3 ==0 && i%5!=0) ret.push_ba

有关包装类拆箱、装箱和整型与字符串型之间的转换

原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5462489.html 1.8种基本数据类型都有各自的包装类,其对应关系为: 基本————————————包装类 byte————————————Byte short———————————Short char————————————Char int————————————Integer long————————————Long float————————————Float double———

时间字段的类型用时间戳整型还是时间类型

不管做什么项目,必须都得接触的东西就是时间类型.现在用时间戳存储日期数据(整型存储)已经是业界很平常的的事情,网上各大游戏公司,各大开源都是采取整型时间戳存储.整数存日期好处很多,程序判断直读,扩展性好,随意可转换xml,json等格式.不过有一个最大的缺点就是查数据库不直观,也就是说我们用管理工具打开数据库的时候,看到的是一堆数字,维护数据不方便.为了解决这一缺陷,我找到一方法,先上代码: select *,DATE_FORMAT(FROM_UNIXTIME(datetimed/1000),"

jinja 语法 - 整型转字符串

大多数 jinja 相关的问题,其实查文档就解决了,但后来遇到这个问题,使得我把 jinja 官方文档,api.样例等,认真读了个遍= =. 发现没有直接的办法可以将整型转为字符串,对于需要进行字符串拼接情况,必须将其进行转换才能使用,不然就会报类型错误.然后 jinja 也不能自定义方法来实现.嘛,看起来似乎没办法了. 最后解决办法是: 我还是试了一下在文档中看到的一个将数组转为字符串的办法:{{ [1, 2, 3]|join }},然后,我试着这样写 {{ [num]|join }},于是就

各种类型转换为字符串类型

字符型转换为字符串 // C 货币 2.5.ToString("C"); // ¥2.50 // D 10进制数 25.ToString("D5"); // 25000 // E 科学型 25000.ToString("E"); // 2.500000E+005 // F 固定点 25.ToString("F2"); // 25.00  "F?"表示保持几位小数 // G 常规 2.5.ToString(&

python之路---03 整型 bool 字符串 for循环

十三.整型(int) 基本操作: 1.+ - * / % // ** 2.  .bit_length() 计算整数在内存中占?的?进制码的?度 如: 十四.布尔值(bool) True  False 1.字符串 => 数字 int() 数字 = > 字符串 str()      x => y类型 y(x)     结论: 想把xxx数据转化成yy类型的数据. yy() 2.能够表示False的数据: 0, "", [], {}, set(), tuple(), Non