Saya yakin semua orang sudah memahami dengan baik perbedaan String dan StringBuffer, namun diperkirakan masih banyak kawan-kawan yang belum paham tentang prinsip kerja kedua kelas ini.Hari ini saya akan mengulas konsep ini untuk semuanya, dan oleh jalannya Ada kelas operasi karakter baru yang diperkenalkan di J2SE 5.0 - StringBuilder. Jadi apa perbedaan antara StringBuilder dan StringBuffer ini dan kelas String yang pertama kali kita temui? Yang mana yang harus kita gunakan dalam situasi berbeda? Saya ingin berbagi pandangan saya tentang kategori-kategori ini, dan saya juga berharap semua orang dapat memberikan pendapatnya. Setiap orang pernah melakukan kesalahan, dan sambil memperbaikinya, ini adalah kesempatan yang baik untuk belajar.
Secara singkat, perbedaan kinerja utama antara tipe String dan tipe StringBuffer sebenarnya adalah bahwa String adalah objek yang tidak dapat diubah (Mengapa? Tanyakan kepada desainer Java, mengapa String bukan tipe asli?) Oleh karena itu, setiap kali tipe String diubah , Faktanya, ini sama dengan membuat objek String baru, dan kemudian mengarahkan penunjuk ke objek String baru. Oleh karena itu, sebaiknya tidak menggunakan String untuk string yang sering mengubah konten. , karena setiap objek dihasilkan akan berdampak pada kinerja sistem. Apalagi jika terlalu banyak objek yang tidak direferensikan di memori, GC JVM akan mulai bekerja, dan kecepatannya pasti akan sangat lambat. Berikut adalah contoh yang sangat tidak tepat:
Jika ini masalahnya, setelah perulangan for selesai, jika objek di memori belum dibersihkan oleh GC, akan ada lebih dari 20.000 di memori, angka yang mencengangkan, dan jika ini adalah sistem yang digunakan oleh banyak orang. orang, maka jumlahnya tidak terlalu banyak, sehingga setiap orang harus berhati-hati dalam menggunakannya.
Jika Anda menggunakan kelas StringBuffer, hasilnya akan berbeda. Setiap kali hasilnya adalah operasi pada objek StringBuffer itu sendiri, alih-alih membuat objek baru dan kemudian mengubah referensi objek. Jadi secara umum kami merekomendasikan penggunaan StringBuffer, terutama ketika objek string sering berubah. Dalam beberapa kasus khusus, rangkaian string objek String sebenarnya ditafsirkan oleh JVM sebagai rangkaian objek StringBuffer, sehingga dalam kasus ini kecepatan objek String tidak akan lebih lambat dibandingkan objek StringBuffer, dan khususnya objek string berikut ini adalah dihasilkan Diantaranya, efisiensi String jauh lebih cepat daripada StringBuffer:
Anda akan terkejut saat mengetahui bahwa kecepatan menghasilkan objek String S1 terlalu cepat, dan saat ini StringBuffer tidak memiliki keunggulan sama sekali dalam hal kecepatan. Faktanya, ini adalah tipuan JVM
Dari sini kita mendapatkan kesimpulan langkah pertama: Dalam kebanyakan kasus, StringBuffer > String
Dan bagaimana StringBuilder membandingkannya dengan mereka? Izinkan saya memperkenalkannya secara singkat terlebih dahulu. StringBuilder adalah kelas yang baru ditambahkan di JDK5.0. Perbedaan antara StringBuffer dan StringBuffer adalah sebagai berikut (sumber: JavaWorld):
Urutan karakter Java.lang.StringBuffer yang aman untuk thread dan dapat diubah. Buffer string mirip dengan String, tetapi tidak dapat dimodifikasi. Buffer string dapat digunakan dengan aman oleh banyak thread. Metode-metode ini dapat disinkronkan bila diperlukan, sehingga semua operasi pada instance tertentu tampak terjadi dalam urutan serial yang konsisten dengan urutan pemanggilan metode yang dilakukan oleh setiap thread yang terlibat.
Setiap buffer string memiliki kapasitas tertentu. Selama panjang urutan karakter yang terdapat dalam buffer string tidak melebihi kapasitas ini, tidak perlu mengalokasikan array buffer internal baru. Kapasitas ini secara otomatis meningkat jika buffer internal meluap. Mulai dari JDK 5.0, kelas setara untuk penggunaan thread tunggal, StringBuilder, telah ditambahkan ke kelas ini. Kelas StringBuilder umumnya harus digunakan sebagai preferensi terhadap kelas ini karena mendukung semua operasi yang sama tetapi lebih cepat karena tidak melakukan sinkronisasi.
Namun tidak aman menggunakan instance StringBuilder dengan banyak thread. Jika sinkronisasi tersebut diperlukan, disarankan untuk menggunakan StringBuffer.
Oleh karena itu, saya rasa semua orang dapat memahami perbedaan di antara keduanya, jadi mari kita buat turunan umum di bawah ini:
Dalam kebanyakan kasus, StringBuilder > StringBuffer
Oleh karena itu, menurut teorema transitif dari pertidaksamaan ini: Dalam kebanyakan kasus, StringBuilder > StringBuffer > String
Sekarang kita sudah mendapatkan hasil derivasi seperti itu, mari kita lakukan tes untuk memverifikasi:
Kode tesnya adalah sebagai berikut:
/** Membuat instance baru dari tessb */
final static int ttime = 10000;//Jumlah loop pengujian
tes publiksb() {
}
tes kekosongan publik(String s){
mulai panjang = System.currentTimeMillis();
untuk(int i=0;i<waktu;i++){
s += "tambahkan";
}
lama berakhir = System.currentTimeMillis();
System.out.println("Waktu yang digunakan oleh operasi jenis "+s.getClass().getName()+" adalah: " + (over - start) + " milidetik" );
}
tes kekosongan publik(StringBuffer s){
mulai panjang = System.currentTimeMillis();
untuk(int i=0;i<waktu;i++){
s.tambahkan("tambahkan");
}
lama berakhir = System.currentTimeMillis();
System.out.println("Waktu yang digunakan oleh operasi jenis "+s.getClass().getName()+" adalah: " + (over - start) + " milidetik" );
}
tes kekosongan publik(StringBuilder s){
mulai panjang = System.currentTimeMillis();
untuk(int i=0;i<waktu;i++){
s.tambahkan("tambahkan");
}
lama berakhir = System.currentTimeMillis();
System.out.println("Waktu yang digunakan oleh operasi jenis "+s.getClass().getName()+" adalah: " + (over - start) + " milidetik" );
}
// Secara langsung menguji penggabungan string pada String
tes kekosongan publik2(){
String s2 = "abadf";
mulai panjang = System.currentTimeMillis();
untuk(int i=0;i<waktu;i++){
Tali s = s2 + s2 + s2 ;
}
lama berakhir = System.currentTimeMillis();
System.out.println("Waktu yang digunakan untuk mengoperasikan tipe penambahan referensi objek string adalah: " + (over - start) + " milidetik" );
}
tes kekosongan publik3(){
mulai panjang = System.currentTimeMillis();
untuk(int i=0;i<waktu;i++){
String s = "abadf" + "abadf" + "abadf" ;
}
lama berakhir = System.currentTimeMillis();
System.out.println("Waktu yang digunakan untuk menambahkan string operasi adalah: "+ (over - start) + " milidetik" );
}
public static void main(String[] args){
String s1="abc";
StringBuffer sb1 = StringBuffer baru("abc");
StringBuilder sb2 = StringBuilder baru("abc");
tessb t = tessb baru();
t.tes(s1);
t.tes(sb1);
t.tes(sb2);
t.test2();
t.test3();
}
}
Tampaknya Anda masih tidak dapat melihat perbedaan antara StringBuffer dan StringBuilder. Tambahkan ttime hingga 30.000 kali dan lihat:
Waktu yang digunakan untuk mengoperasikan tipe java.lang.String adalah : 53444 milidetik Waktu yang digunakan untuk mengoperasikan tipe java.lang.StringBuffer adalah : 15 milidetik Waktu yang digunakan untuk mengoperasikan tipe java.lang.StringBuilder adalah : 15 milidetik Waktu digunakan untuk mengoperasikan tipe penambahan referensi objek string Waktu yang dibutuhkan: 31 milidetik Penambahan string membutuhkan waktu: 0 milidetik
Masih tidak banyak perbedaan kinerja antara StringBuffer dan StringBuilder. Mari kita tingkatkan menjadi 100000 dan lihat. Kami tidak akan menambahkan pengujian untuk tipe String di sini, karena pengujian data dalam jumlah besar untuk tipe String akan dilakukan sangat lambat...
Waktu yang dibutuhkan untuk mengoperasikan tipe java.lang.StringBuffer adalah: 31 milidetik Waktu yang dibutuhkan untuk mengoperasikan tipe java.lang.StringBuilder adalah: 16 milidetik
Anda dapat melihat perbedaannya, tetapi banyak hasil pengujian yang menunjukkan bahwa StringBuffer lebih cepat daripada StringBuilder. Mari kita tingkatkan nilainya menjadi 1000000 dan lihat (seharusnya tidak crash, bukan?):
Waktu yang dibutuhkan untuk mengoperasikan tipe java.lang.StringBuffer adalah: 265 milidetik Waktu yang dibutuhkan untuk mengoperasikan tipe java.lang.StringBuilder adalah: 219 milidetik
Perbedaannya lebih sedikit, dan hasilnya sangat stabil. Mari kita lihat lebih besar, ttime = 5000000:
・・・・・・ Pengecualian di thread "utama" java.lang.OutOfMemoryError: Java heap space ・・・・・・
Haha lupakan saja, saya tidak akan mengujinya lagi. Pada dasarnya, kinerjanya adalah StringBuilder > StringBuffer > String.