Java中StringBuilder和StringBuffer的区别

1. String,StringBuilder和StringBuffer

String是final类,并且String对象一经创建就不可更改。值得注意的是final类不可被继承,因而String类创建出来的是静态的字符串常量。StringBuilder和StringBuffer是字符串变量。他们皆是继承自AbstractStringBuilder。

2. StringBuilder和StringBuffer的区别

1)同步

StringBuffer和String一样始自JDK1.0。StringBuffer中大部分方法都有synchronized关键字修饰,因而其是线程安全的。
例如:

    @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

StringBuilder是JDK1.5新增的,该类大部分方法没有关键字synchronized,其不是线程安全的。因为不用考虑同步,因而提高了操作的性能。同时,该类提供了一个与StringBuffer兼容的 API。
例如:

    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

2)缓冲区

在toString方法上,StringBuffer每次获取字符串都会是直接用toStringCache来生成字符串而StringBuilder则每次都需要复制一次字符数组,然后再构造String。(通俗说就是如果字符串没有改变,多次使用toString时StringBuffer可以直接用缓存的toStringCache,而StringBuilder则无此设计)

//StringBuffer
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
//StringBuilder
    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

3)性能

在性能上,对于少量的字符串操作,String不用新建类,因而方便使用。当需要处理的字符串操作很多时,字符串变量的类StringBuilder和StringBuffer会更有优势。
下面进行三个实验:

  1. 进行字符串"a"与"b"拼接并输出
  2. 进行字符串"1"到"100000"拼接并输出
  3. 在多线程下进行字符串大量操作时其实就只能使用StringBuffer了,因而此部分不做实验。

对于实验1:(取的是其中一个实验数据,多次实验结果一致)

CLASSTASKTIME
String输出“ab”5.561E-4 s
StringBuilder输出“ab”2.09E-5 s
StringBuffer输出“ab”8.6E-5 s

对于实验2:(取的是其中一个实验数据,多次实验结果一致)

CLASSTASKTIME
String输出1到10000017.6074861 s
StringBuilder输出1到1000000.0113411 s
StringBuffer输出1到1000000.0155818 s

附上实验1与实验2的代码

public class StringSearch {
    // 测试实验一操作所需要的时间,单位:秒
    private static double test1(){
        long startTime = System.nanoTime();
        String s="a";
        s=s+"b";
        System.out.println(s);
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }
    private static double test2(){
        long startTime = System.nanoTime();
        StringBuffer s=new StringBuffer("a");
        s.append("b");
        System.out.println(s.toString());
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }
    private static double test3(){
        long startTime = System.nanoTime();
        StringBuilder s=new StringBuilder("a");
        s.append("b");
        System.out.println(s.toString());
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }

    public static void main(String[] args) {

        double time1 = test1();
        System.out.println("String, time: " + time1 + " s");

        double time2 = test2();
        System.out.println("StringBuffer, time: " + time2 + " s");

        double time3 = test3();
        System.out.println("StringBuilder, time: " + time3 + " s");
    }
}
public class StringSearch {
    // 测试实验二操作所需要的时间,单位:秒
    private static double test1(){
        long startTime = System.nanoTime();
        String s="";
        for(int i=1;i<=100000;i++)
            s=s+i;
        System.out.println(s);
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }
    private static double test2(){
        long startTime = System.nanoTime();
        StringBuffer s=new StringBuffer();
        for(int i=1;i<=100000;i++)
            s=s.append(i);
        System.out.println(s.toString());
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }
    private static double test3(){
        long startTime = System.nanoTime();
        StringBuilder s=new StringBuilder();
        for(int i=1;i<=100000;i++)
            s=s.append(i);
        System.out.println(s.toString());
        long endTime = System.nanoTime();
        return (endTime - startTime) / 1000000000.0;
    }

    public static void main(String[] args) {

        double time1 = test1();
        System.out.println("String, time: " + time1 + " s");

        double time2 = test2();
        System.out.println("StringBuffer, time: " + time2 + " s");

        double time3 = test3();
        System.out.println("StringBuilder, time: " + time3 + " s");
    }
}

参考资料:
https://blog.csdn.net/qushaming/article/details/82971901

https://blog.csdn.net/youanyyou/article/details/86504755

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值