string,stringBuffer,stringBuild区别与联系

(1)string

       1,Stirng是对象不是基本数据类型 
       2,String是final类,不能被继承。是不可变对象,一旦创建,就不能修改它的值。 
       3,对于已经存在的Stirng对象,修改它的值,就是重新创建一个对象,然后将新值赋予这个对象 

 不可改变的Unicode字符序列
池化思想,把需要共享的数据放在池中,用一个存储区域来存放一些公用资源  以减少存储空间的开销。
在String类中,以字面值创建时,会到Java方法空间的串池中去查找,如果没有则会在串池里创建一个字符串对象,并返回其地址赋给对象变量,如果有就返回串池中字符串的地址,并把这个地址赋给对象变量。
如果是new,则会在堆空间中创建String类的对象,不会有上述的过程
如:
String s1 = "abc";  //新创建,字符串常量池中没有该串,则会在池中创建一个串"abc"
String s2 = "abc";  //串池中已经存在"abc",则s2会去指向"abc"而不会去创建一个新的
    String s3 = new String("abc");  //直接在堆中去开辟一个新的空间,而不会去池中查找
类中的具体方法查看下Api文档。
调用任何String中的方法,不会改变String自身,除非重新赋值。

(2)stringBuffer

   1,一个类似于 String 的字符串缓冲区,对它的修改的不会像String那样重创建对象。 
   2,使用append()方法修改Stringbuffer的值,使用toString()方法转换为字符串。

   3,线程安全,效率低 

 可改变的Unicode字符序列
允许并发操作,是线程安全的
String类在进行字符串连接时会显得效率很低,就是因为它所产生的对象的属性是不能够修改的,当连接字符串时也就只能创建新的对象。
对于很多字符串连接时,应当使用StringBuffer类,使用这个类的对象来进行字符串连接时就不会有多余的中间对象生成,从而优化了效率。
例:对于字符串连接String str = "A" + "B" + "C" + "D";
产生:"AB"、"ABC"、"ABCD"
在串池中产生的"AB"、"ABC"明显是多余对象,浪费空间。
                     解决方案:
String s = null;
StringBuffer sb = new StringBuffer("A");
sb.append("B");
sb.append("C");
sb.append("D");
s = sb.toString();
 

(3)stringBuild

       是jdk1.5后用来替换stringBuffer的一个类,大多数时候可以替换StringBuffer。和StringBuffer的区别在于Stringbuild是一个单线程使用的类,

  不执行线程同步所以比 StringBuffer的速度快,效率高。是线程非安全的。

可改变的Unicode字符序列
操作同StringBuffer,只是不支持并发操作,非线程安全
 

(4)区别,联系

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

        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来操作,查看结果 
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多倍,而且随着循环次数的增加这个差距逐渐增大 

猜你喜欢

转载自www.cnblogs.com/autumn-rains/p/11673870.html