StringBuffer和StringBuilder之间的主要区别是什么?在决定其中任何一项时是否存在性能问题?


当前回答

StringBuilder比StringBuffer更快,因为StringBuffer是同步的,StringBuffer有自己的char[]缓冲区用于缓存,就像BufferedInputStream一样。

StringBuffer速度较慢的另一个原因是,每次添加或删除时,它都会更新变量缓冲区。我测试了它,如果我移除超过一万次,StringBuffer的移除方法会更快。

其他回答

StringBuffer用于存储将要更改的字符串(字符串对象不能更改)。它会根据需要自动展开。相关类:String、CharSequence。

StringBuilder是在Java5中添加的。它在所有方面都与StringBuffer相同,只是它不同步,这意味着如果多个线程同时访问它,可能会出现问题。对于单线程程序,最常见的情况是,避免同步开销会使StringBuilder稍微快一些。

一个简单的程序说明了StringBuffer和StringBuilder之间的区别:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

字符串缓冲区

同步,因此线程安全线程安全,因此速度较慢

字符串拼接

在Java 5.0中引入异步,因此快速高效用户明确需要同步它,如果他想您可以将其替换为StringBuffer而无需任何其他更改

StringBuilder比StringBuffer更快,因为StringBuffer是同步的,StringBuffer有自己的char[]缓冲区用于缓存,就像BufferedInputStream一样。

StringBuffer速度较慢的另一个原因是,每次添加或删除时,它都会更新变量缓冲区。我测试了它,如果我移除超过一万次,StringBuffer的移除方法会更快。

StringBuilder比StringBuffer更快,因为它不同步。

下面是一个简单的基准测试:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

测试运行得出StringBuffer为2241ms,StringBuilder为753ms。