Ringkasan
StringBuilder dan StringBuffer adalah dua konsep yang mudah membingungkan. Artikel ini dimulai dari kode sumber dan hanya melihat persamaan dan perbedaan antara keduanya.
Sangat mudah untuk mengetahui bahwa salah satu dari keduanya aman-aman, dan yang aman-utas tidak efisien.
Deskripsi di java doc
Java Doc adalah anotasi yang ditulis oleh orang -orang yang menulis kode sumber. Mari kita lihat Java Doc dulu.
StringBuilder
Urutan karakter yang dapat berubah. Kelas ini memberikan 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 digunakan oleh satu utas (seperti yang umumnya terjadi). Jika memungkinkan, disarankan agar kelas ini digunakan dalam preferensi untuk StringBuffer karena akan lebih cepat di bawah sebagian besar implementasi.
Operasi utama pada StringBuilder adalah metode yang ditambahkan dan dimasukkan, yang kelebihan beban untuk menerima data jenis apa pun. Masing -masing secara efektif mengubah datum yang diberikan ke string dan kemudian menambahkan atau menyisipkan karakter string itu ke pembangun string. Metode Append selalu menambahkan karakter ini di ujung pembangun; Metode insert menambahkan karakter pada titik yang ditentukan.
Misalnya, jika Z mengacu pada objek pembangun string yang isinya saat ini "mulai", maka metode tersebut memanggil z.append ("le") akan menyebabkan pembangun string mengandung "kejutan", sedangkan z.insert (4, "le") akan mengubah pembangun string untuk berisi "Starlet".
Secara umum, jika referer SB ke instance dari StringBuilder, maka SB.Append (x) memiliki efek yang sama dengan SB.insert (sb.length (), x).
Setiap pembangun string memiliki kapasitas. Selama panjang urutan karakter yang terkandung dalam pembangun string tidak melebihi kapasitas, tidak perlu untuk mengalokasikan buffer internal baru. Jika buffer internal meluap, secara otomatis dibuat lebih besar.
Contoh StringBuilder tidak aman untuk digunakan oleh banyak utas. Jika sinkronisasi tersebut diperlukan maka disarankan agar java.lang.stringbuffer digunakan.
Kecuali disebutkan sebaliknya, meneruskan argumen nol ke konstruktor atau metode di kelas ini akan menyebabkan nullpointerException dilemparkan.
Sejak:
1.5
Pengarang:
Michael McCloskey
Lihat juga:
java.lang.stringbuffer
java.lang.string
StringBuffer
Urutan karakter yang aman dan dapat berubah. Buffer string seperti string, tetapi dapat dimodifikasi. Pada titik mana pun itu berisi beberapa urutan karakter tertentu, tetapi panjang dan konten urutan dapat diubah melalui panggilan metode tertentu.
Buffer string aman untuk digunakan oleh banyak utas. Metode disinkronkan jika diperlukan sehingga semua operasi pada contoh tertentu berperilaku seolah -olah terjadi dalam beberapa urutan serial yang konsisten dengan urutan panggilan metode yang dibuat oleh masing -masing utas individu yang terlibat.
Operasi utama pada StringBuffer adalah metode yang ditambahkan dan dimasukkan, yang kelebihan beban untuk menerima data jenis apa pun. Masing -masing secara efektif mengonversi datum yang diberikan ke string dan kemudian menambahkan atau menyisipkan karakter string itu ke buffer string. Metode Append selalu menambahkan karakter ini di ujung buffer; Metode insert menambahkan karakter pada titik yang ditentukan.
Misalnya, jika Z mengacu pada objek buffer string yang isinya saat ini "mulai", maka metode itu memanggil z.append ("le") akan menyebabkan buffer string berisi "mengejutkan", sedangkan z.insert (4, "le") akan mengubah buffer string untuk berisi "starlet".
Secara umum, jika referer SB ke instance dari StringBuffer, maka SB.Append (x) memiliki efek yang sama dengan SB.insert (sb.length (),
Setiap kali suatu operasi terjadi yang melibatkan urutan sumber (seperti menambahkan atau memasukkan dari urutan sumber), kelas ini hanya menyinkronkan pada buffer string yang melakukan operasi, bukan pada sumber. Perhatikan bahwa sementara StringBuffer dirancang agar aman digunakan secara bersamaan dari beberapa utas, jika konstruktor atau operasi append atau insert dilewatkan urutan sumber yang dibagi di seluruh utas, kode panggilan harus memastikan bahwa operasi memiliki tampilan yang konsisten dan tidak berubah dari urutan sumber selama durasi operasi. Ini dapat dipenuhi oleh penelepon yang memegang kunci selama panggilan operasi, dengan menggunakan urutan sumber yang tidak dapat diubah, atau dengan tidak berbagi urutan sumber di seluruh utas.
Setiap buffer string memiliki kapasitas. Selama panjang urutan karakter yang terkandung dalam buffer string tidak melebihi kapasitas, tidak perlu untuk mengalokasikan array buffer internal baru. Jika buffer internal meluap, secara otomatis dibuat lebih besar.
Kecuali disebutkan sebaliknya, meneruskan argumen nol ke konstruktor atau metode di kelas ini akan menyebabkan nullpointerException dilemparkan.
Pada rilis JDK 5, kelas ini telah dilengkapi dengan kelas yang setara yang dirancang untuk digunakan oleh satu utas, StringBuilder. Kelas StringBuilder umumnya harus digunakan dalam preferensi untuk yang ini, karena mendukung semua operasi yang sama tetapi lebih cepat, karena tidak melakukan sinkronisasi.
Sejak:
Jdk1.0
Pengarang:
Arthur Van Hoff
Lihat juga:
java.lang.stringbuilder
java.lang.string
Ringkasan Javadoc
Dari atas, kita dapat melihat:
Baik StringBuffer dan StringBuilder dapat dianggap sebagai string variabel.
StringBuffer aman-utas dan muncul lebih dulu, dan tersedia di JDK1.0.
StringBuilder tidak aman dan muncul kemudian dan hanya ada di JDK1.5.
Antarmuka keduanya persis sama, dan StringBuilder lebih cepat.
Bahkan, ada baiknya menggunakannya secara normal, hanya tahu poin -poin ini, tetapi saya masih ingin melihat bagaimana itu diimplementasikan dalam kode sumber.
Kode Sumber
Cara mencapai keamanan utas
Anda dapat melihat dari kode sumber yang keduanya mewarisi kelas abstrak AbstractStringBuilder
Publik Kelas Akhir StringBuffer Memperluas AbstractStringBuilder mengimplementasikan java.io.serializable, charequencePublic Kelas akhir StringBuilder memperluas abstractStringBuilder mengimplementasikan java.io.serializable, charsequence
Jumlah kode tidak terlalu besar, baris kode StringBuilder440, stringBuffer718 baris kode, dan yang paling banyak adalah AbstractStringBuilder, dengan total 1440 baris kode.
Dari beberapa perspektif, kami melihat kode, yang merupakan seperti apa beberapa struktur internal utama, dan yang lainnya adalah bagaimana fungsi yang biasanya kami gunakan diimplementasikan. Karena string tidak dapat diubah, ditempatkan di kolam konstan. Dapat ditebak bahwa StringBuilder dan StringBuffer harus diimplementasikan menggunakan array char.
/*** Nilainya digunakan untuk penyimpanan karakter. */ nilai char []; /*** Hitungannya adalah jumlah karakter yang digunakan. */ jumlah int;
Dapat dilihat bahwa data disimpan dengan nilai dan panjangnya diwakili oleh hitungan.
Mari kita lihat berbagai implementasi dari beberapa metode umum.
StringBuffer
@Override Public Sinkronisasi StringBuffer append (string str) {toStringcache = null; super.append (str); kembalikan ini; } / ** * @throws StringIndExoutOfBoundsException {@inHeritDoc} * / @Override Public Sinkronisasi StringBuffer Insert (int offset, string str) {toStringCache = null; super.insert (offset, str); kembalikan ini; } @Override Public Sinkronisasi string toString () {if (toStringcache == null) {toStringcache = arrays.copyofrange (value, 0, count); } return string baru (ToStringCache, true); }StringBuilder
@Override public stringBuilder append (string str) {super.append (str); kembalikan ini; } / ** * @throws StringIndExoutOfBoundsException {@inHeritDoc} * / @Override Public StringBuilder Insert (int offset, string str) {super.insert (offset, str); kembalikan ini; } @Override Public String ToString () {// Buat salinan, jangan bagikan array mengembalikan string baru (value, 0, count); }Seperti yang dapat dilihat dari kode, dalam kebanyakan kasus, StrinbBuffer hanya menambahkan kata kunci yang disinkronkan untuk memastikan keamanan utas. Tetapi metode tostring berbeda, jadi saya akan membicarakannya nanti.
Inisialisasi ukuran dan cara tumbuh
Karena itu sebenarnya adalah array, ukuran dan metode pertumbuhan array yang dimulai dari sangat penting. Mari kita lihat kode.
/** * Membangun buffer string tanpa karakter di dalamnya dan * kapasitas awal 16 karakter. */ public stringBuffer () {super (16); } /** * Membangun pembangun string tanpa karakter di dalamnya dan * kapasitas awal 16 karakter. */ public stringBuilder () {super (16); }Seperti yang Anda lihat, kedua konstruktor default ini menunjukkan bahwa ukuran array default adalah 16.
Mengapa 16? Saya tidak mengerti.
Apa yang selanjutnya khawatir tentang bagaimana tumbuh? Mari kita lihat implementasi Append
public abstractStringBuilder append (string str) {if (str == null) return appendNull (); int len = str.length (); Ensurecapacityinternal (Count + Len); str.getchars (0, len, nilai, hitungan); hitung += len; kembalikan ini; } /** * Metode ini memiliki kontrak yang sama dengan Ensurecapacity, tetapi * tidak pernah disinkronkan. */ private void ensurecapacityinternal (int minimumcapacity) {// overflow -consent code if (minimumCapacity - value.length> 0) Expandapacity (minimumcapacity); } /** * Ini mengimplementasikan semantik ekspansi Ensurecapacity tanpa periksa atau sinkronisasi ukuran *. */ void expandcapacity (int minimumCapacity) {int newCapacity = value.length * 2 + 2; if (newcapacity - minimumcapacity <0) newCapacity = minimumcapacity; if (newcapacity <0) {if (minimumcapacity <0) // overflow new outofmemoryError (); newCapacity = integer.max_value; } value = arrays.copyof (value, newcapacity); }Tiga metode di atas menjelaskan cara memperluas kapasitas.
Letakkan kapasitas saat ini *2+2
Jika panjang yang baru ditambahkan lebih besar dari nilai ini, diatur ke nilai yang baru ditambahkan
Jika meluap, lempar outofmemoryError
Implementasi ToString di StringBuffer
/*** cache nilai terakhir yang dikembalikan oleh tostring. Dibersihkan * Setiap kali StringBuffer dimodifikasi. */ char transien pribadi [] tostringcache; @Override Public Sinkronisasi StringBuffer append (string str) {toStringcache = null; super.append (str); kembalikan ini; } @Override Public Sinkronisasi string toString () {if (toStringcache == null) {toStringcache = arrays.copyofrange (value, 0, count); } return string baru (ToStringCache, true); }Seperti yang Anda lihat, array tostringcache didefinisikan. Setiap kali data berubah, ini diatur ke NULL. Saat tostring, ambil lagi dari data saat ini.
Kata kunci sementara adalah untuk mencegah array ini menjadi serial.
ringkasan
Faktanya, kode sumber Java itu sendiri relatif sederhana. Jika Anda dapat memulai dengan kode sumber, Anda dapat memahami banyak prinsip lebih dalam. Artikel ini hanya mencantumkan beberapa kode sumber dan secara singkat menjelaskan persamaan dan perbedaan antara StringBuffer dan StringBuilder. Teman -teman yang tertarik dapat melihatnya sendiri.
Artikel di atas secara singkat melihat persamaan dan perbedaan antara StringBuilder dan StringBuffer dari perspektif kode sumber (analisis komprehensif) adalah semua konten yang saya bagikan dengan Anda. Saya harap ini dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.