java入门到精通学习笔记 String, StringBuilder, StringBuffer

来源:互联网 发布:软件开发项目风险管理 编辑:程序博客网 时间:2024/06/06 17:39

亲自写下代码验证一下三种方法的性能:


public static long strAddTimer(){long count = 10000;long beginTime = System.currentTimeMillis();String str="stringAddTest";for (int i=0; i<count;i++){str=str+"add";}long endTime = System.currentTimeMillis();System.out.print("strTimer:");System.out.println(endTime-beginTime);return endTime-beginTime;}public static long strBuilderTimer(){long count = 100000;long beginTime = System.currentTimeMillis();StringBuilder strBuilder= new StringBuilder("stringAddTest");for (int i=0; i<count;i++){strBuilder.append("add");}long endTime = System.currentTimeMillis();System.out.print("strBuilderTimer:");System.out.println((endTime-beginTime));return endTime-beginTime;}public static long strBufferTimer(){long count = 100000;long beginTime = System.currentTimeMillis();StringBuffer strBuffer= new StringBuffer("stringAddTest");for (int i=0; i<count;i++){strBuffer.append("add");}long endTime = System.currentTimeMillis();System.out.print("strBufferTimer:");System.out.println((endTime-beginTime));return endTime-beginTime;}
<p class="p1"><span class="s1">public</span> <span class="s1">static</span> <span class="s1">void</span> main(String[] <span class="s2">args</span>){</p><p class="p3"><span class="s3"><span></span><span></span></span>StrOperation.strAddTimer();</p><p class="p1"><span></span><span></span>StrOperation.strBufferTimer();</p><p class="p1"><span></span><span></span>StrOperation.strBuilderTimer();</p><p class="p1"><span style="font-family: Arial, Helvetica, sans-serif;">}</span></p><p class="p1"><span style="font-family: Arial, Helvetica, sans-serif;"></span></p><p class="p1">输出结果为:</p><p class="p1">strTimer:213</p><p class="p1">strBufferTimer:9</p><p class="p1">strBuilderTimer:4</p>

由此得出结论: 在单线程运行时,这三类性能优劣依次是 StringBuilder, StringBuffer, String.

仔细剖析,以下摘自网络:

1. String 类
   String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。
   String a = "a"; //假设a指向地址0x0001
   a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。
   因此String的操作都是改变赋值地址而不是改变值操作。

2. StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。

3. StringBuffer  v.s. StringBuilder: 相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类。String类是不可变类,任何对String的改变都会引发新的String对象的生成;而StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象,可变和不可变类这一对对象已经齐全了,那么为什么还要引入新的StringBuilder类干吗?相信大家都有此疑问,我也如此。下面,我们就来看看引入该类的原因。

      为什么会出现那么多比较String和StringBuffer的文章?

      原因在于当改变字符串内容时,采用StringBuffer能获得更好的性能。既然是为了获得更好的性能,那么采用StringBuffer能够获得最好的性能吗?

      答案是NO!

      为什么?

      如果你读过《Think in Java》,而且对里面描述HashTable和HashMap区别的那部分章节比较熟悉的话,你一定也明白了原因所在。对,就是支持线程同步保证线程安全而导致性能下降的问题。HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也在于此,新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。

0 0