Perbedaan antara StringBuilder dan StringBuffer


Jawaban:


1667

StringBufferdisinkronkan, StringBuildertidak.


239
dan StringBuilder dimaksudkan sebagai penurunan pengganti StringBuffer mana sinkronisasi tidak diperlukan
Joel

95
dan sinkronisasi hampir tidak pernah diperlukan. Jika seseorang ingin menyinkronkan pada StringBuilder, mereka hanya dapat mengelilingi seluruh blok kode dengan disinkronkan (sb) {} pada contoh
locka

23
@locka Saya berpendapat bahwa StringBuffer tidak pernah merupakan ide yang baik (kecuali jika Anda memiliki API yang memerlukannya) vanillajava.blogspot.de/2013/04/…
Peter Lawrey

8
Satu-satunya tempat yang saya lihat untuk StringBuffer adalah konsol seperti keluaran dan berbagai utilitas pencatatan: banyak utas mungkin menghasilkan konflik. Karena Anda tidak ingin 2 output ikut campur ... tetapi biasanya sinkronisasi pada level StringBuffer adalah level terlalu rendah, Anda akan ingin menyinkronkan pada appender seperti levelm sehingga locka jawaban adalah yang terbaik dan StringBuffer harus dihentikan. Ini akan menghemat waktu ulasan kode dengan pemula.
Remi Morin

20
Mnemonik yang baik bagi mereka yang mencampur keduanya - BuFFer adalah Pertama, lebih tua, dan karenanya disinkronkan. Kelas Builder baru menggunakan pola Builder dan asinkron.
Datageek

728

StringBuilderlebih cepat daripada StringBufferkarena tidaksynchronized .

Berikut ini adalah tes benchmark sederhana:

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);
        }
    }
}

Sebuah uji coba memberikan angka 2241 msuntuk StringBuffervs 753 msuntuk StringBuilder.


10
Saya mengubah string literal menjadi sesuatu yang lebih besar: "rubah cokelat cepat" dan mendapatkan hasil yang lebih menarik. Pada dasarnya, mereka cepat. Saya benar-benar kehabisan memori jadi saya harus menghapus beberapa tujuh. Penjelasan: sinkronisasi dioptimalkan oleh hotspot. Anda pada dasarnya hanya mengukur waktu yang dibutuhkan hotspot untuk melakukan ini (dan mungkin beberapa optimasi lainnya).
Jilles van Gurp

7
Anda perlu melakukan pemanasan sebelumnya. Tes ini tidak adil untuk StringBuffer. Juga, akan lebih baik jika itu benar-benar menambahkan sesuatu. Sebenarnya, saya membalik tes, dan menambahkan string acak dan mendapat tes sebaliknya. Bisa dikatakan, bahwa seseorang tidak bisa mempercayai tolok ukur sederhana. Yang sebaliknya menunjukkan StringBuffer lebih cepat. 5164 untuk StringBuilder vs 3699 untuk StringBuffer hastebin.com/piwicifami.avrasm
mmm

75
Ini adalah pertama kalinya saya melihat --> 0dalam satu lingkaran. Butuh waktu sejenak bagi saya untuk menyadari apa artinya itu. Apakah ini sesuatu yang sebenarnya digunakan dalam praktik alih-alih ...; i > 0; i--sintaks yang biasa ?
Raimund Krämer

19
Itu i -->benar-benar mengganggu sintaksis ... Saya pikir itu panah pada awalnya karena komentar tentang seni ASCII.
Sameer Puri

14
Yang lain menyimpulkan dengan hasil yang berbeda: alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html . Patok banding harus benar-benar dilakukan dengan JMH, bukan dengan yang sederhana. main()Juga, patokan Anda tidak adil. Tidak ada pemanasan.
Lukas Eder

249

Pada dasarnya, StringBuffermetode disinkronkan sementara StringBuildertidak.

Operasi "hampir" sama, tetapi menggunakan metode yang disinkronkan dalam satu utas terlalu banyak.

Cukup banyak tentang itu.

Kutipan dari StringBuilder API :

Kelas ini [StringBuilder] menyediakan API yang kompatibel dengan StringBuffer, tetapi tanpa jaminan sinkronisasi . Kelas ini dirancang untuk digunakan sebagai pengganti drop-in untuk StringBuffer di tempat-tempat di mana buffer string sedang digunakan oleh utas tunggal (seperti umumnya casing). Jika memungkinkan, disarankan agar kelas ini digunakan dalam preferensi untuk StringBuffer karena akan lebih cepat di sebagian besar implementasi.

Jadi itu dibuat untuk menggantikannya.

Hal yang sama terjadi dengan Vectordan ArrayList.


1
Juga dengan Hashtabledan HashMap.
shmosel

177

Tetapi perlu untuk mendapatkan perbedaan yang jelas dengan bantuan contoh?

StringBuffer atau StringBuilder

Cukup gunakan StringBuilderkecuali Anda benar-benar mencoba berbagi buffer di antara utas. StringBuilderadalah adik laki-laki yang tidak disinkronkan (kurang overhead = lebih efisien) dari StringBufferkelas yang disinkronkan asli .

StringBufferdatang dulu. Sun prihatin dengan kebenaran dalam semua kondisi, jadi mereka membuatnya disinkronkan agar benang aman untuk berjaga-jaga.

StringBuilderdatang kemudian. Sebagian besar penggunaan StringBufferadalah utas tunggal dan tidak perlu membayar biaya sinkronisasi.

Karena StringBuildermerupakan pengganti drop-in untukStringBuffer tanpa sinkronisasi, tidak akan ada perbedaan antara contoh apa pun.

Jika Anda sedang mencoba untuk berbagi antara benang, Anda dapat menggunakan StringBuffer, tapi mempertimbangkan apakah tingkat yang lebih tinggi sinkronisasi diperlukan, misalnya mungkin bukan menggunakan StringBuffer, Anda harus melakukan sinkronisasi metode yang menggunakan StringBuilder.


14
Jawaban bagus pertama !! Intinya adalah "kecuali Anda berbagi buffer antara utas"
AlexWien

1
jawaban yang sangat rinci!
Raúl

81

Pertama mari kita lihat kesamaan : Baik StringBuilder dan StringBuffer bisa berubah. Itu berarti Anda dapat mengubah kontennya, dengan di lokasi yang sama.

Perbedaan : StringBuffer bisa berubah dan disinkronkan juga. Sedangkan StringBuilder bisa berubah tetapi tidak disinkronkan secara default.

Arti disinkronkan (sinkronisasi) : Ketika beberapa hal disinkronkan, maka beberapa utas dapat mengakses, dan memodifikasinya tanpa masalah atau efek samping. StringBuffer disinkronkan, sehingga Anda dapat menggunakannya dengan banyak utas tanpa masalah.

Yang mana yang harus digunakan kapan? StringBuilder: Ketika Anda membutuhkan sebuah string, yang dapat dimodifikasi, dan hanya satu utas yang mengakses dan memodifikasinya. StringBuffer: Ketika Anda membutuhkan sebuah string, yang dapat dimodifikasi, dan beberapa utas mengakses dan memodifikasinya.

Catatan : Jangan gunakan StringBuffer secara tidak perlu, yaitu, jangan menggunakannya jika hanya satu utas yang memodifikasi dan mengaksesnya karena memiliki banyak kode penguncian dan pembukaan kunci untuk sinkronisasi yang tidak perlu menghabiskan waktu CPU. Jangan gunakan kunci kecuali jika diperlukan.


2
Hanya ingin menyebutkan bahwa panggilan metode INDIVIDUAL StringBuffer adalah thread-safe. Tetapi jika Anda memiliki beberapa baris kode, gunakan blok kode yang disinkronkan untuk menjamin keamanan thread, dengan beberapa kunci / monitor (seperti biasa ...). Pada dasarnya, jangan hanya berasumsi bahwa menggunakan pustaka aman thread segera menjamin keamanan thread dalam program ANDA!
Kevin Lee

57

Dalam utas tunggal, StringBuffer tidak secara signifikan lebih lambat dari StringBuilder , berkat optimisasi JVM. Dan dalam multithreading, Anda tidak dapat menggunakan StringBuilder dengan aman.

Ini tes saya (bukan benchmark, hanya tes):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Hasil:
string: 319740
Buffer: 23
Builder: 7!

Jadi Builder lebih cepat daripada Buffer, dan WAY lebih cepat daripada string strings. Sekarang mari kita gunakan Pelaksana untuk banyak utas:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Sekarang StringBuffers mengambil 157 ms untuk 100000 penambahan. Ini bukan tes yang sama, tetapi dibandingkan dengan 37 ms sebelumnya, Anda dapat dengan aman menganggap bahwa menambahkan StringBuffers lebih lambat dengan penggunaan multithreading . Alasannya adalah bahwa JIT / hotspot / compiler / something membuat optimisasi ketika mendeteksi bahwa tidak perlu memeriksa kunci.

Tetapi dengan StringBuilder, Anda memiliki java.lang.ArrayIndexOutOfBoundsException , karena utas bersamaan mencoba menambahkan sesuatu yang seharusnya tidak ada.

Kesimpulannya adalah Anda tidak perlu mengejar StringBuffers. Dan di mana Anda memiliki utas, pikirkan tentang apa yang mereka lakukan, sebelum mencoba untuk mendapatkan beberapa nanodetik.


5
Anda lupa melakukan "t0 = System.currentTimeMillis ();" sebelum melakukan tes StringBuilder. Jadi gambar yang ditampilkan untuk StringBuilder sebenarnya adalah waktu yang diperlukan untuk menjalankan tes stringbuffer DAN stringbuilder. Tambahkan baris ini dan Anda akan melihat bahwa StringBuilder lebih cepat sekitar DUA KALI.
Gena Batsyan

Perhatikan bahwa withString+="some string"+i+" ; ";tidak setara dengan dua loop lainnya dan karenanya bukan perbandingan yang adil.
Dave Jarvis

Tepat, diperbaiki. String pemikiran masih sangat lambat.
Nicolas Zozol

Bisakah Anda jelaskan lebih lanjut mengapa peningkatan ArrayIndexOutOfBoundsException untuk StringBuilder
Alireza Fattahi

Anda harus menggunakan JMH untuk benchmark. Benchmark Anda benar-benar tidak akurat.
Lukas Eder

42

StringBuilder diperkenalkan di Java 1.5 sehingga tidak akan bekerja dengan JVM sebelumnya.

Dari Javadocs :

Kelas StringBuilder menyediakan API yang kompatibel dengan StringBuffer, tetapi tanpa jaminan sinkronisasi. Kelas ini dirancang untuk digunakan sebagai pengganti drop-in untuk StringBuffer di tempat-tempat di mana buffer string sedang digunakan oleh utas tunggal (seperti umumnya casing). Jika memungkinkan, disarankan agar kelas ini digunakan dalam preferensi untuk StringBuffer karena akan lebih cepat di sebagian besar implementasi.


13
1.4 ada di Akhir Masa Layanannya, jadi sepertinya tidak ada yang perlu dikhawatirkan sebelum 1.5.
Tom Hawtin - tackline

@ tomHawtin-tackline belum tentu - ada produk perusahaan di luar sana pada pra 1.4 yang sebagian besar dari kita gunakan setiap hari. Juga BlackBerry java didasarkan pada 1.4 dan itu masih sangat baru.
Richard Le Mesurier

Dan CDC dan CLDC tidak punya StringBuilder.
Jin Kwon

37

Pertanyaan Yang Cukup Bagus

Inilah perbedaannya, saya perhatikan:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

Hal yang biasa :-

Keduanya memiliki metode yang sama dengan tanda tangan yang sama. Keduanya bisa berubah.


23

StringBuffer

  • Disinkronkan karenanya threadsafe
  • Thread aman karenanya lambat

StringBuilder

  • Diperkenalkan di Jawa 5.0
  • Asynchronous karenanya cepat & efisien
  • Pengguna secara eksplisit perlu menyinkronkannya, jika ia mau
  • Anda dapat menggantinya dengan StringBuffertanpa perubahan lainnya

CATATAN: Hanya operasi tunggal yang aman dari thread, beberapa operasi tidak. mis. jika Anda menelepon appenddua kali, atau appenddan toStringtidak aman.
Peter Lawrey

22

StringBuilder tidak aman untuk thread. String Buffer adalah. Info lebih lanjut di sini .

EDIT: Mengenai kinerja, setelah hotspot dimulai, StringBuilder adalah pemenangnya. Namun, untuk iterasi kecil, perbedaan kinerja dapat diabaikan.


21

StringBuilderdan StringBufferhampir sama. Perbedaannya adalah yang StringBufferdisinkronkan dan StringBuildertidak. Meskipun, StringBuilderlebih cepat daripada StringBuffer, perbedaan kinerja sangat sedikit. StringBuilderadalah pengganti SUN dari StringBuffer. Itu hanya menghindari sinkronisasi dari semua metode publik. Daripada itu, fungsi mereka sama.

Contoh penggunaan yang baik:

Jika teks Anda akan berubah dan digunakan oleh banyak utas, maka lebih baik digunakan StringBuffer. Jika teks Anda akan berubah tetapi digunakan oleh utas tunggal, maka gunakan StringBuilder.


19

StringBuffer

StringBuffer bisa berubah artinya seseorang dapat mengubah nilai objek. Objek yang dibuat melalui StringBuffer disimpan di heap. StringBuffer memiliki metode yang sama dengan StringBuilder, tetapi setiap metode di StringBuffer disinkronkan yaitu StringBuffer aman untuk thread.

karena ini tidak memungkinkan dua utas untuk secara bersamaan mengakses metode yang sama. Setiap metode dapat diakses oleh satu utas sekaligus.

Tetapi menjadi thread aman juga memiliki kelemahan karena kinerja hit StringBuffer karena properti thread aman. Dengan demikian StringBuilder lebih cepat daripada StringBuffer saat memanggil metode yang sama dari setiap kelas.

Nilai StringBuffer dapat diubah, itu berarti dapat ditetapkan ke nilai baru. Saat ini pertanyaan wawancara yang paling umum, perbedaan antara kelas-kelas di atas. String Buffer dapat dikonversi ke string dengan menggunakan metode toString ().

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder sama dengan StringBuffer, yaitu ia menyimpan objek di heap dan juga dapat dimodifikasi. Perbedaan utama antara StringBuffer dan StringBuilder adalah bahwa StringBuilder juga tidak aman. StringBuilder cepat karena tidak aman untuk thread.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

masukkan deskripsi gambar di sini

Sumber: String Vs StringBuffer Vs StringBuilder


StringBuilder tidak dapat diubah dan tipe String dapat berubah
Brinda Rathod

Saya tidak akan setuju bahwa Strings dan StringBuilders "cepat" dan StringBuffers "sangat lambat". Lihat jawaban di atas.
FireCubez

17

String adalah kekal.

StringBuffer adalah bisa berubah dan disinkronkan.

StringBuilder juga bisa berubah tetapi tidak disinkronkan.


Selain itu, StringBuffer mengunci Thread untuk mengakses data aman utas ini sehingga operasi berjalan lambat. StringBuilder tidak mengunci utas dan itu berjalan dalam cara Multi Threading itu sebabnya cepat. String - ketika Anda tidak perlu menggabungkan string ini adalah cara yang baik, tetapi ketika Anda membutuhkannya menggunakan StringBuilder -> karena String menciptakan setiap kali objek baru di heap, tetapi StringBuilder mengembalikan objek yang sama ...
Musa

11

The javadoc menjelaskan perbedaan:

Kelas ini menyediakan API yang kompatibel dengan StringBuffer, tetapi tanpa jaminan sinkronisasi. Kelas ini dirancang untuk digunakan sebagai pengganti drop-in untuk StringBuffer di tempat-tempat di mana buffer string sedang digunakan oleh utas tunggal (seperti umumnya casing). Jika memungkinkan, disarankan agar kelas ini digunakan dalam preferensi untuk StringBuffer karena akan lebih cepat di sebagian besar implementasi.


10

StringBuilder (diperkenalkan di Java 5) identik dengan StringBuffer , kecuali metodenya tidak disinkronkan. Ini berarti memiliki kinerja yang lebih baik daripada yang terakhir, tetapi kekurangannya adalah tidak aman.

Baca tutorial untuk lebih jelasnya.


6

Sebuah program sederhana yang menggambarkan perbedaan antara StringBuffer dan 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");
        }

    }
}

4

StringBuffer digunakan untuk menyimpan string karakter yang akan diubah (objek String tidak dapat diubah). Secara otomatis mengembang sesuai kebutuhan. Kelas terkait: String, CharSequence.

StringBuilder ditambahkan di Java 5. Ini identik dalam semua hal dengan StringBuffer kecuali bahwa itu tidak disinkronkan, yang berarti bahwa jika beberapa utas mengaksesnya pada saat yang sama, mungkin ada masalah. Untuk program single-threaded, kasus yang paling umum, menghindari overhead sinkronisasi membuat StringBuilder sangat cepat


4
Program single-threaded bukan kasus yang paling umum di Jawa, tetapi StringBuilderlocals biasanya lokal untuk suatu metode, di mana mereka terlihat hanya satu utas.
finnw

4

StringBufferdisinkronkan, tetapi StringBuildertidak. Akibatnya, StringBuilderlebih cepat dari StringBuffer.


4

StringBuffer bisa berubah. Itu dapat berubah dalam hal panjang dan konten. StringBuffers aman digunakan, yang berarti bahwa mereka memiliki metode yang disinkronkan untuk mengontrol akses sehingga hanya satu utas yang dapat mengakses kode tersinkronisasi objek StringBuffer sekaligus. Dengan demikian, objek StringBuffer umumnya aman untuk digunakan dalam lingkungan multi-threaded di mana beberapa thread mungkin mencoba mengakses objek StringBuffer yang sama pada saat yang sama.

StringBuilder Kelas StringBuilder sangat mirip dengan StringBuffer, kecuali bahwa aksesnya tidak disinkronkan sehingga tidak aman untuk thread. Dengan tidak disinkronkan, kinerja StringBuilder bisa lebih baik daripada StringBuffer. Jadi, jika Anda bekerja di lingkungan single-threaded, menggunakan StringBuilder sebagai ganti StringBuffer dapat menghasilkan peningkatan kinerja. Ini juga berlaku untuk situasi lain seperti variabel lokal StringBuilder (yaitu, variabel dalam suatu metode) di mana hanya satu utas yang akan mengakses objek StringBuilder.


4

StringBuffer:

  • Multi-Utas
  • Disinkronkan
  • Lebih lambat dari StringBuilder

StringBuilder

  • Single-Thread
  • Tidak Disinkronkan
  • Lebih cepat dari sebelumnya

2
Lebih tepatnya, String c = a + bsama dengan String c = new StringBuilder().append(a).append(b).toString(), jadi tidak lebih cepat. Ini hanya bahwa Anda membuat yang baru untuk setiap penugasan string yang, sementara Anda bisa memiliki hanya satu ( String d = a + b; d = d + c;yang String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();sementara StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();akan menyimpan satu StringBuilder instanciation).
Potong

4

Pembuat String :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

Penyangga-Tali

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

Dianjurkan untuk menggunakan StringBuilder kapan pun dimungkinkan karena lebih cepat daripada StringBuffer. Namun, jika keamanan utas diperlukan, opsi terbaik adalah objek StringBuffer.


Jika Anda membutuhkan keamanan utas, opsi terbaik adalah menggunakan StringBuilder karena StringBuffer hanya aman untuk operasi individual. Untuk beberapa operasi, Anda perlu mengunci secara eksplisit.
Peter Lawrey

4

Penggunaan yang lebih baik StringBuilderkarena tidak disinkronkan dan karenanya menawarkan kinerja yang lebih baik. StringBuilderadalah pengganti dari yang lebih lama StringBuffer.


3
@Ark benar tetapi sebagian besar waktu StringBu(ff|ild)eradalah variabel lokal yang hanya digunakan oleh satu utas.
gabuzo

1
@MarkMcKenna: Bahkan dalam aplikasi multi-threaded, kita sering harus menggunakan penguncian eksternal, atau melakukan pekerjaan ekstra untuk menghindarinya. Misalnya, jika dua utas masing-masing ingin menambahkan catatan yang berisi beberapa string ke pembuat string, mereka harus menggabungkan data yang akan ditambahkan dan kemudian menambahkannya sebagai satu unit bahkan jika itu akan lebih cepat - tidak ada masalah threading-- untuk hanya melakukan urutan operasi penambahan diskrit.
supercat

3

Karena StringBufferdisinkronkan, perlu beberapa upaya ekstra, karenanya berdasarkan kinerja, ini agak lambat StringBuilder.


3

Tidak ada perbedaan mendasar antara StringBuilderdan StringBuffer, hanya ada beberapa perbedaan di antara mereka. Dalam StringBuffermetode disinkronkan. Ini berarti bahwa pada suatu waktu hanya satu utas yang dapat beroperasi pada mereka. Jika ada lebih dari satu utas maka utas kedua harus menunggu yang pertama selesai dan yang ketiga harus menunggu yang pertama dan yang kedua selesai dan seterusnya. Ini membuat proses sangat lambat dan karenanya kinerja dalam kasusStringBuffer rendah.

Di sisi lain, StringBuildertidak disinkronkan. Ini berarti bahwa pada suatu waktu beberapa utas dapat beroperasi pada StringBuilderobjek yang sama pada saat yang sama. Ini membuat proses sangat cepat dan karenanya kinerja StringBuildertinggi.


3

A Stringadalah objek yang tidak dapat diubah yang artinya nilainya tidak dapat diubah sementara StringBufferitu bisa berubah.

Ini StringBufferDisinkronkan karenanya thread-safe sedangkan StringBuildertidak dan hanya cocok untuk instance single-threaded.


3
hanya karena StringBuffer memiliki kode yang disinkronkan, tidak berarti StringBuffer adalah threadsafe. Pertimbangkan contoh berikut: StringBuffer testingBuffer = "stackoverflow"; Sekarang Thread-1 mencoba menambahkan "1" ke testingBuffer, dan Thread-2 mencoba menambahkan "2" ke testingBuffer. Sekarang meskipun metode append () disinkronkan, Anda tidak dapat memastikan apakah nilai testingBuffer akan menjadi "stackoverflow12" atau "stackoverflow21". Sebenarnya, disarankan oleh Oracle untuk menggunakan stringbuilder di atas stringbuffer. Saya harap ini membantu :)
Biman Tripathy

2

Perbedaan utama StringBufferadalah disinkronkan tetapi StringBuildertidak. Jika Anda perlu menggunakan lebih dari satu utas, maka StringBuffer direkomendasikan. Namun, sesuai kecepatan eksekusi StringBuilderlebih cepat daripada StringBuffer, karena tidak disinkronkan.


4
StringBuffer hanya aman jika Anda melakukan hanya satu operasi di atasnya. Saya tidak akan merekomendasikan menggunakannya di banyak utas karena sangat sulit untuk memperbaikinya.
Peter Lawrey

@ PeterLawrey apa maksudmu :-)
Tamad Lang

1
@ b16db0 Maksud saya sebagian besar penggunaan StringBuffer tidak aman karena mereka membuat beberapa panggilan ke sana tanpa sinkronisasi eksternal, membuat kelas agak tidak berguna.
Peter Lawrey

@PeterLawrey ah itu seperti StringBuffer masih membutuhkan lingkungan yang disinkronkan.
Tamad Lang

2

Periksa internal metode StringBufferpenambahan yang disinkronkan dan metode penambahan yang tidak disinkronkan dari StringBuilder.

StringBuffer :

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder :

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

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

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Karena append adalah synchronized, StringBuffermemiliki overhead kinerja dibandingkan dengan StrinbBuilderskenario multi-threading. Selama Anda tidak berbagi buffer di antara beberapa utas, gunakan StringBuilder, yang cepat karena tidak adanya synchronizedmetode tambahan.


1

Berikut ini adalah hasil pengujian kinerja untuk String vs StringBuffer vs StringBuilder . Akhirnya, StringBuilder memenangkan Tes. Lihat di bawah ini untuk kode uji dan hasil.

Kode :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Eksekusi saya pada ideone

Hasil :

100000 iterasi untuk menambahkan satu teks

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

10000 iterasi untuk menambahkan satu teks

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

1
  • StringBuffer aman untuk thread tetapi StringBuilder tidak aman untuk thread.
  • StringBuilder lebih cepat dari StringBuffer.
  • StringBuffer disinkronkan sedangkan StringBuilder tidak disinkronkan.

1

StringBuffer disinkronkan dan aman, StringBuilder tidak disinkronkan dan lebih cepat.


Perbedaan ini telah diberikan dalam semua jawaban lain untuk pertanyaan ini. Bisakah Anda menyoroti sesuatu yang baru?
Nico Haase
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.