1、可变性

String不可变,StringBuffer和StringBuilder可变

2、运行速度

StringBuilder > StringBuffer > String

String最慢是因为它是字符串常量,一旦创建对象,其值不可更改,而StringBuffer和StringBuilder是字符串变量,其值可以改变。(以下代码为例)

public class example {
    public static void main(String[] args) {
        String str = "abcd";
        System.out.println(str);
        str = str + "fg";
        System.out.println(str);
    }
}

这段代码的运行结果首先输出“abcd”,然后又输出“abcdfg”,感觉str这个对象值被更改了,实际上并没有,JVM是这样处理的,先创建一个String对象str,然后把“abcd”赋值给str,然后,在第三行代码中,JVM又创建了一个新的对象也叫str,然后把原来的str值加上“fg”赋值给新的str,原来的str会被GC(垃圾回收机制)给回收。所以,实际上str并没有更改值。

实际上Java对String对象的操作就是不断创建新的对象并且将旧的对象给回收的一个过程,所以执行速度很慢。而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

        long a=new Date().getTime();
        String cc="";
        int n=10000;
        for (int i = 0; i < n; i++) {
            cc+="."+i;
        }
        System.out.println("String使用的时间"+(System.currentTimeMillis()-a)/1000.0+"s");
        long s1=System.currentTimeMillis();
        StringBuilder sb=new StringBuilder();
        for (int i = 0; i < n; i++) {
            sb.append("."+i);
        }
        System.out.println("StringBuilder使用的时间"+(System.currentTimeMillis()-s1)/1000.0+"s");
        long s2=System.currentTimeMillis();
        StringBuffer sbf=new StringBuffer();
        for (int i = 0; i < n; i++) {
            sbf.append("."+i);
        }
        System.out.println("StringBuffer使用的时间"+(System.currentTimeMillis()-s2)/1000.0+"s");

运行结果如下:

3、线程安全

 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

 如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

(一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞)(来源于网络。)

最后:

  String:适用于少量的字符串操作的情况

   StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

   StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

发表回复

您的电子邮箱地址不会被公开。