Saat bekerja di aplikasi Java, saya baru-baru ini perlu menyusun daftar nilai yang dipisahkan koma untuk dilewatkan ke layanan web lain tanpa mengetahui berapa banyak elemen yang akan ada di muka. Yang terbaik yang bisa saya dapatkan dari atas kepala saya adalah sesuatu seperti ini:
public String appendWithDelimiter( String original, String addition, String delimiter ) {
if ( original.equals( "" ) ) {
return addition;
} else {
return original + delimiter + addition;
}
}
String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );
Saya menyadari ini tidak terlalu efisien, karena ada string yang dibuat di semua tempat, tapi saya akan mencari kejelasan lebih dari optimasi.
Di Ruby, saya bisa melakukan sesuatu seperti ini, yang terasa jauh lebih elegan:
parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");
Tetapi karena Java tidak memiliki perintah join, saya tidak dapat menemukan yang setara.
Jadi, apa cara terbaik untuk melakukan ini di Jawa?
Jawaban:
Pra Jawa 8:
Apache commons lang adalah teman Anda di sini - ini menyediakan metode bergabung yang sangat mirip dengan yang Anda lihat di Ruby:
StringUtils.join(java.lang.Iterable,char)
Java 8:
Java 8 menyediakan bergabung keluar dari kotak melalui
StringJoiner
danString.join()
. Cuplikan di bawah ini menunjukkan bagaimana Anda dapat menggunakannya:StringJoiner
String.join(CharSequence delimiter, CharSequence... elements))
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
sumber
Anda bisa menulis sedikit metode utilitas gaya gabungan yang berfungsi di java.util.Lists
Kemudian gunakan seperti ini:
sumber
List<String>
intitializer Anda keIterator<?>
dan memiliki efek yang sama?Dalam kasus Android, kelas StringUtils dari commons tidak tersedia, jadi untuk ini saya gunakan
http://developer.android.com/reference/android/text/TextUtils.html
sumber
The perpustakaan Jambu Google memiliki com.google.common.base.Joiner kelas yang membantu untuk menyelesaikan tugas-tugas tersebut.
Sampel:
Berikut adalah artikel tentang utilitas string Guava .
sumber
Di Java 8 Anda dapat menggunakan
String.join()
:Lihat juga jawaban ini untuk contoh API Aliran.
sumber
Anda dapat menggeneralisasikannya, tetapi tidak ada yang bergabung di Jawa, seperti yang Anda katakan.
Ini mungkin bekerja lebih baik.
sumber
Iterable<String>
dan gunakan saja fakta bahwa Anda dapat mengulanginya. Dalam contoh Anda, Anda tidak perlu jumlah item dalam koleksi, jadi ini bahkan lebih umum.StringBuilder
gantinya. Mereka identik, kecualiStringBuffer
memberikan keamanan utas yang tidak perlu. Bisakah seseorang mengeditnya!isEmpty()
metode, gunakannext()
metode inidi Java 8 Anda dapat melakukan ini seperti:
jika daftar memiliki nol Anda dapat menggunakan:
itu juga mendukung awalan dan sufiks:
sumber
Gunakan pendekatan berdasarkan
java.lang.StringBuilder
! ("Urutan karakter yang bisa berubah.")Seperti yang Anda sebutkan, semua rangkaian string itu menciptakan String di seluruh.
StringBuilder
tidak akan melakukan itu.Kenapa
StringBuilder
bukannyaStringBuffer
? DariStringBuilder
javadoc:sumber
Saya akan menggunakan Google Collections. Ada fasilitas Gabung yang bagus.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html
Tetapi jika saya ingin menulisnya sendiri,
Saya pikir ini berfungsi lebih baik dengan koleksi objek, karena sekarang Anda tidak perlu mengubah objek Anda menjadi string sebelum Anda bergabung dengan mereka.
sumber
Kelas Apache commons StringUtils memiliki metode bergabung.
sumber
Java 8
sumber
Anda dapat menggunakan
StringBuilder
tipe Java untuk ini. Ada jugaStringBuffer
, tetapi ini berisi logika keselamatan ulir ekstra yang seringkali tidak perlu.sumber
Dan yang minimal (jika Anda tidak ingin memasukkan Apache Commons atau Gauva ke dalam dependensi proyek hanya untuk bergabung dengan string)
sumber
Gunakan StringBuilder dan kelas
Separator
Pemisah membungkus pembatas. Pembatas dikembalikan dengan
toString
metode Separator , kecuali pada panggilan pertama yang mengembalikan string kosong!Kode sumber untuk kelas
Separator
sumber
Separator
sehingga menggunakanStringBuilder
alih - alih penggabunganStrings
?Separator
baru saja mengembalikan pembatas, itu tidak menyatukan string itu sendiri.Separator
??? Kenapa tidak menggunakan String sederhana saja ..?!Mengapa tidak menulis metode join () Anda sendiri? Itu akan mengambil sebagai parameter koleksi String dan String pembatas. Dalam metode iterate atas koleksi dan membangun hasil Anda di StringBuffer.
sumber
Jika Anda menggunakan Spring MVC maka Anda dapat mencoba langkah-langkah berikut.
Itu akan menghasilkan
a,b,c
sumber
Jika Anda menggunakan Eclipse Collections , Anda dapat menggunakan
makeString()
atauappendString()
.makeString()
mengembalikanString
representasi, mirip dengantoString()
.Itu memiliki tiga bentuk
makeString(start, separator, end)
makeString(separator)
default dimulai dan diakhiri dengan string kosongmakeString()
default pemisah untuk", "
(koma dan spasi)Contoh kode:
appendString()
mirip denganmakeString()
, tetapi ditambahkan keAppendable
(sukaStringBuilder
) danvoid
. Ini memiliki tiga bentuk yang sama, dengan argumen pertama tambahan, Appendable.Jika Anda tidak dapat mengonversi koleksi Anda ke jenis Eclipse Collections, cukup sesuaikan dengan adaptor yang relevan.
Catatan: Saya pengendara untuk koleksi Eclipse.
sumber
Java 8 Jenis Asli
Java 8 Custom Object:
sumber
Anda mungkin harus menggunakan a
StringBuilder
denganappend
metode untuk membangun hasil Anda, tetapi jika tidak, ini adalah solusi yang bagus seperti yang ditawarkan Java.sumber
Mengapa Anda tidak melakukan di Jawa hal yang sama dengan yang Anda lakukan di ruby, yaitu membuat string pembatas dipisahkan hanya setelah Anda menambahkan semua bagian ke array?
Anda mungkin ingin memindahkannya untuk loop dalam metode helper terpisah, dan juga menggunakan StringBuilder alih-alih StringBuffer ...
Sunting : memperbaiki urutan penambahan.
sumber
Dengan Java 5 variabel args, jadi Anda tidak perlu memasukkan semua string Anda ke dalam koleksi atau array secara eksplisit:
sumber
Bagi mereka yang berada dalam konteks Musim Semi kelas StringUtils mereka berguna juga:
Ada banyak cara pintas yang bermanfaat seperti:
dan banyak lagi.
Ini bisa membantu jika Anda belum menggunakan Java 8 dan Anda sudah berada dalam konteks Musim Semi.
Saya lebih suka melawan Apache Commons (walaupun sangat bagus juga) untuk dukungan Koleksi yang lebih mudah seperti ini:
sumber
Anda dapat mencoba sesuatu seperti ini:
sumber
Jadi pada dasarnya sesuatu seperti ini:
sumber
Tidak tahu apakah ini benar-benar lebih baik, tapi setidaknya itu menggunakan StringBuilder, yang mungkin sedikit lebih efisien.
Di bawah ini adalah pendekatan yang lebih umum jika Anda dapat membangun daftar parameter SEBELUM melakukan pembatasan parameter apa pun.
sumber
Pendekatan Anda tidak terlalu buruk, tetapi Anda harus menggunakan StringBuffer alih-alih menggunakan tanda +. + Memiliki kerugian besar bahwa instance String baru sedang dibuat untuk setiap operasi tunggal. Semakin lama string Anda, semakin besar biaya overhead. Jadi menggunakan StringBuffer harus menjadi cara tercepat:
Setelah Anda selesai membuat string, cukup panggil toString () pada StringBuffer yang dikembalikan.
sumber
Alih-alih menggunakan penggabungan string, Anda harus menggunakan StringBuilder jika kode Anda tidak di-thread, dan StringBuffer jika benar.
sumber
Anda membuat ini sedikit lebih rumit dari yang seharusnya. Mari kita mulai dengan akhir dari contoh Anda:
Dengan perubahan kecil menggunakan StringBuilder alih-alih sebuah String, ini menjadi:
Setelah selesai (saya berasumsi Anda harus memeriksa beberapa kondisi lain juga), pastikan Anda menghapus koma tailing dengan perintah seperti ini:
Dan akhirnya, dapatkan string yang Anda inginkan
Anda juga bisa mengganti "," di panggilan kedua untuk menambahkan dengan string pembatas umum yang dapat diatur untuk apa saja. Jika Anda memiliki daftar hal-hal yang Anda tahu perlu Anda tambahkan (tanpa syarat), Anda bisa memasukkan kode ini ke dalam metode yang mengambil daftar string.
sumber
sumber
Jadi, beberapa hal yang mungkin Anda lakukan untuk merasakan bahwa sepertinya Anda sedang mencari:
1) Perluas kelas Daftar - dan tambahkan metode bergabung ke dalamnya. Metode join hanya akan melakukan pekerjaan menggabungkan dan menambahkan pembatas (yang bisa menjadi param untuk metode join)
2) Sepertinya Java 7 akan menambahkan metode ekstensi ke java - yang memungkinkan Anda hanya melampirkan metode tertentu ke kelas: sehingga Anda dapat menulis metode bergabung itu dan menambahkannya sebagai metode ekstensi ke Daftar atau bahkan untuk Koleksi.
Solusi 1 mungkin adalah satu-satunya yang realistis, sekarang, karena Java 7 belum keluar :) Tapi seharusnya berfungsi dengan baik.
Untuk menggunakan keduanya, Anda hanya perlu menambahkan semua item Anda ke Daftar atau Koleksi seperti biasa, dan kemudian memanggil metode kustom baru untuk 'bergabung' dengan mereka.
sumber