Stringbuffer与Stringbuilder源码学习和对比

String/StringBuffer/StringBuilder的异同

(1)相同点
观察源码会发现,三个类都是被final修饰的,是不可被继承的。
(2)不同点
String的对象是不可变的;而StringBuilder和StringBuffer是可变的
查看源码可以发现,StringBuffer的实现都添加了Synchronized同步,因此StringBuffer是线程安全的,而StringBuilder不是线程安全的
String中的offset,value,count都是被final修饰的不可修改的;而StringBuffer和StringBuilder中的value,count都是继承自AbstractStringBuilder类的,没有被final修饰,说明他们在运行期间是可修改的,而且没有offset变量。


StringBuffer/StringBuilder源码学习

String底层是一个char数组:

1
private  final  char  value[];

同样,StringBuffer/StringBuilder都继承了AbstractStringBuilder,
底层的实现也是通过一个char型数组:

1
char [] value;

它们的默认构造方法都是初始化一个长度为16的字符数组,

1
2
3
4
5
6
7
public  StringBuilder() {
        super ( 16 );
    }
    
  public  StringBuilder() {
        super ( 16 );
    }

或者使用传入的容量进行初始化:

1
2
3
4
5
6
7
public  StringBuilder( int  capacity) {
         super (capacity);
     }
     
   public  StringBuffer( int  capacity) {
         super (capacity);
     }

再具体的实现就不去看了,有用到再研究。

使用举例

贴一个以前学习Java的例子,

String s1 = “hello”; 
s1=“world”; 
这个操作其实是:其实是创建了两个String对象。

String s2 = "hello" 
s2 += "world"; 
这操作是:先创建一个String对象,在接下来进行字符串连接的时候,有创建了一个StringBuilder(jdk1.5前是StringBuffer),然后调用append()方法,最后调用toString()方法。 
有此可以看出String对字符的操作比直接使用Stringbuffer(或者StringBuild)要多出附加的操作,而且String是不可变对象,使用String对字符串操作会产生大量的、多余java对象。所以结果是:影响性能,占用空间。 
举例: 
分别使用String和StringBuffer对字符串“0123456789”累加10000次,然后统计耗时多长:

1
2
3
4
5
6
7
8
9
10
String str =  "0123456789" ;
     String str2 =  "" ;
    int  count =  10000 ;
     long  start = System.currentTimeMillis();
     for  ( int  i =  0 ; i < count; i++) {
        str2 += str;
     }
     long  end = System.currentTimeMillis();
     long  time = (end - start);
     System.out.println(time);

  

运行多次,在我的机器上平均时间约等于3300,即3.3秒,下面用StringBuffer来操作,查看结果

1
2
3
4
5
6
7
8
9
10
11
String str =  "0123456789" ;
StringBuffer sb =  new  StringBuffer();
int  count =  10000 ;
long  start = System.currentTimeMillis();
for  ( int  i =  0 ; i < count; i++) {
sb.append(str);
}
String str2 = sb.toString();
long  end = System.currentTimeMillis();
long  time = (end - start);
System.out.println(time);

  

同样在我的机器上结果平均结果小于10,即0.01秒,两者相差300多倍,而且随着循环次数的增加这个差距逐渐增大 。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值