读书人

StringBuilder与StringBuffer的差别(转

发布时间: 2012-12-28 10:29:04 作者: rapoo

StringBuilder与StringBuffer的区别(转)

相信大家看到过很多比较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高。如果你对此不太相信,可以试试下面的例子:

package com.hct.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
?* @author: chengtai.he
?* @created:2009-12-9 上午09:59:57
?*/
public class StringBuilderTester {
?private static final String base = " base string. ";
?private static final int count = 2000000;

?public static void stringTest() {
??long begin, end;
??begin = System.currentTimeMillis();
??String test = new String(base);
??for (int i = 0; i < count/100; i++) {
???test = test + " add ";
??}
??end = System.currentTimeMillis();
??System.out.println((end - begin)
????+ " millis has elapsed when used String. ");
?}

?public static void stringBufferTest() {
??long begin, end;
??begin = System.currentTimeMillis();
??StringBuffer test = new StringBuffer(base);
??for (int i = 0; i < count; i++) {
???test = test.append(" add ");
??}
??end = System.currentTimeMillis();
??System.out.println((end - begin)
????+ " millis has elapsed when used StringBuffer. ");
?}

?public static void stringBuilderTest() {
??long begin, end;
??begin = System.currentTimeMillis();
??StringBuilder test = new StringBuilder(base);
??for (int i = 0; i < count; i++) {
???test = test.append(" add ");
??}
??end = System.currentTimeMillis();
??System.out.println((end - begin)
????+ " millis has elapsed when used StringBuilder. ");
?}

?public static String appendItemsToStringBuiler(List list) {
??StringBuilder b = new StringBuilder();

??for (Iterator i = list.iterator(); i.hasNext();) {
???b.append(i.next()).append(" ");
??}

??return b.toString();
?}

?public static void addToStringBuilder() {
??List list = new ArrayList();
??list.add(" I ");
??list.add(" play ");
??list.add(" Bourgeois ");
??list.add(" guitars ");
??list.add(" and ");
??list.add(" Huber ");
??list.add(" banjos ");

??System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
?}

?public static String appendItemsToStirngBuffer(List list) {
??StringBuffer b = new StringBuffer();

??for (Iterator i = list.iterator(); i.hasNext();) {
???b.append(i.next()).append(" ");
??}

??return b.toString();
?}

?public static void addToStringBuffer() {
??List list = new ArrayList();
??list.add(" I ");
??list.add(" play ");
??list.add(" Bourgeois ");
??list.add(" guitars ");
??list.add(" and ");
??list.add(" Huber ");
??list.add(" banjos ");

??System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
?}

?public static void main(String[] args) {
??stringTest();
??stringBufferTest();
??stringBuilderTest();
??addToStringBuffer();
??addToStringBuilder();
?}
}

上面的程序结果如下:
5266 millis has elapsed when used String.
375 millis has elapsed when used StringBuffer.
281 millis has elapsed when used StringBuilder.
?I?? play?? Bourgeois?? guitars?? and?? Huber?? banjos?
?I?? play?? Bourgeois?? guitars?? and?? Huber?? banjos
从上面的结果来看,这三个类在单线程程序中的性能差别一目了然,采用String对象时,即使运行次数仅是采用其他对象的1/100,其执行时间仍然比其他对象高出25倍以上;而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显,前者是后者的1.5倍左右。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;当然,如果要保证线程安全,自然非StringBuffer莫属了。

除了对多线程的支持不一样外,这两个类的使用几乎没有任何差别,上面的例子就是个很好的说明。appendItemsToStringBuiler和appendItemsToStirngBuffer两个方法除了采用的对象分别为StringBuilder和StringBuffer外,其他完全相同,而效果也完全相同。

?

来自:http://www.cnblogs.com/Fskjb/archive/2010/04/19/1715176.html

读书人网 >编程

热点推荐