Saya punya ArrayList
yang ingin saya hasilkan sepenuhnya sebagai String. Pada dasarnya saya ingin menampilkannya dengan menggunakan toString
masing-masing elemen yang dipisahkan oleh tab. Apakah ada cara cepat untuk melakukan ini? Anda dapat mengulanginya (atau menghapus setiap elemen) dan menggabungkannya ke sebuah String tetapi saya pikir ini akan sangat lambat.
353
Jawaban:
Pada dasarnya, menggunakan loop untuk beralih di atas
ArrayList
adalah satu-satunya pilihan:JANGAN gunakan kode ini, lanjutkan membaca di bagian bawah jawaban ini untuk melihat mengapa itu tidak diinginkan, dan kode mana yang harus digunakan sebagai gantinya:
Bahkan, rangkaian string akan baik-baik saja, karena
javac
kompiler akan mengoptimalkan rangkaian string sebagai serangkaianappend
operasi padaStringBuilder
pokoknya. Berikut adalah bagian dari pembongkaran bytecode darifor
loop dari program di atas:Seperti yang dapat dilihat, kompiler mengoptimalkan loop itu dengan menggunakan
StringBuilder
, jadi kinerja seharusnya tidak menjadi perhatian besar.(OK, pada pandangan kedua,
StringBuilder
sedang dipakai pada setiap iterasi dari loop, jadi itu mungkin bukan bytecode paling efisien. Instantiating dan menggunakan eksplisitStringBuilder
mungkin akan menghasilkan kinerja yang lebih baik.)Bahkan, saya berpikir bahwa memiliki segala jenis output (baik itu ke disk atau ke layar) akan setidaknya urutan besarnya lebih lambat daripada harus khawatir tentang kinerja rangkaian string.
Sunting: Seperti yang ditunjukkan dalam komentar, optimisasi kompiler di atas memang membuat contoh baru
StringBuilder
pada setiap iterasi. (Yang telah saya catat sebelumnya.)Teknik yang paling optimal untuk digunakan akan menjadi respons oleh Paul Tomblin , karena hanya instantiate satu
StringBuilder
objek di luarfor
loop.Menulis ulang kode di atas ke:
Hanya akan membuat instantiate di
StringBuilder
luar loop, dan hanya membuat dua panggilan keappend
metode di dalam loop, seperti dibuktikan dalam bytecode ini (yang menunjukkan instantiationStringBuilder
dan loop):Jadi, memang optimasi tangan harus berkinerja lebih baik, karena bagian dalam
for
loop lebih pendek dan tidak perlu instantiateStringBuilder
pada setiap iterasi.sumber
Java
atau Geewax forAndroid
Di Java 8 atau lebih baru:
Jika
list
bukan tipe String, kolektor gabungan dapat digunakan:sumber
Jika Anda kebetulan melakukan ini di Android, ada utilitas bagus untuk ini yang disebut TextUtils yang memiliki
.join(String delimiter, Iterable)
metode.Jelas tidak banyak digunakan di luar Android, tetapi saya pikir saya akan menambahkannya ke utas ini ...
sumber
TextUtils.join
mengambilObject[]
, saya menganggap itu memanggiltoString()
setiap token. ApakahPatientDetails
menerapkantoString()
? Jika itu tidak menyelesaikan masalah, Anda mungkin terjebak melakukan sesuatu denganSeparator
kelas.org.apache.lang3.StringUtils
melakukan hal yang hampir sama, jadi jawaban Anda benar-benar bermanfaat bagi saya di luar Android :)Unduh Apache Commons Lang dan gunakan metode ini
Anda dapat mengimplementasikannya sendiri, tentu saja, tetapi kode mereka sepenuhnya diuji dan mungkin merupakan implementasi terbaik.
Saya penggemar berat perpustakaan Apache Commons dan saya juga berpikir itu merupakan tambahan yang bagus untuk Java Standard Library.
sumber
StringUtils.join(list.toArray(),"\t")
Ini adalah pertanyaan yang cukup lama, tetapi saya pikir saya mungkin juga menambahkan jawaban yang lebih modern - gunakan
Joiner
kelas dari Guava :sumber
Mengubah Daftar menjadi String yang dapat dibaca dan bermakna adalah pertanyaan umum yang mungkin dihadapi setiap orang.
Kasus 1 . Jika Anda memiliki StringUtils apache di jalur kelas Anda (seperti dari rogerdpack dan Ravi Wallau):
Kasus 2 . Jika Anda hanya ingin menggunakan cara dari JDK (7):
Hanya tidak pernah membuat roda sendiri, jangan gunakan lingkaran untuk tugas satu baris ini.
sumber
Arrays.toString(myList.toArray())
- solusi termudah dan paling mudahArrays.toString(list.toArray())
mudah untuk ditulis, tetapi sangat tidak efisien.Jika Anda mencari one-liner cepat, pada Java 5 Anda dapat melakukan ini:
Selain itu, jika tujuan Anda hanya untuk mencetak konten dan kurang peduli tentang "\ t", Anda dapat melakukan ini:
yang mengembalikan string seperti
Jika Anda memiliki Array (bukan ArrayList) maka Anda dapat melakukan hal yang sama seperti ini:
sumber
m
rumah tangga din
kota-kota dix
negara bagian, Anda akan mengatakan ituO(mnx)
atauO(n^3)
, tetapi saya dapat menguraikannya kembali dengan mengatakan "cari orang ini di negara ini," dan Anda akan segera memberi tahu sayaO(n)
. Selain itu, semua algoritma di sini pada umumnyaO(n)
, tidak ada perulangan di dalam satu lingkaran.Loop melalui itu dan panggil toString. Tidak ada cara ajaib, dan jika ada, menurut Anda apa yang akan dilakukannya di balik selimut selain mengulanginya? Tentang satu-satunya optimasi mikro adalah menggunakan StringBuilder, bukan String, dan bahkan itu bukan kemenangan besar - string gabungan berubah menjadi StringBuilder di bawah selimut, tetapi setidaknya jika Anda menulisnya dengan cara itu Anda dapat melihat apa yang terjadi.
sumber
Sebagian besar proyek Java sering memiliki apache-commons lang tersedia. Metode StringUtils.join () sangat bagus dan memiliki beberapa rasa untuk memenuhi hampir setiap kebutuhan.
sumber
join(...)
metode ini memiliki varian untuk array dan koleksi.Android memiliki kelas TextUtil, Anda dapat menggunakan http://developer.android.com/reference/android/text/TextUtils.html
sumber
Untuk kasus penggunaan sederhana ini, Anda dapat dengan mudah menggabungkan string dengan koma. Jika Anda menggunakan Java 8:
jika tidak commons-lang memiliki metode join ():
sumber
Cara yang elegan untuk berurusan dengan karakter pemisahan yang tertinggal adalah dengan menggunakan Pemisah Kelas
Metode toString dari Class Separator mengembalikan separater, kecuali untuk panggilan pertama. Jadi kami mencetak daftar tanpa tertinggal (atau dalam hal ini) pemisah terkemuka.
sumber
Di Java 8 itu sederhana. Lihat contoh untuk daftar bilangan bulat:
Atau versi multiline (yang lebih mudah dibaca):
Perbarui - versi yang lebih pendek
sumber
filter
. Pada akhirnya jauh lebih mudah bagi saya untuk membaca kodenya.String
juga. Jika ini adalah daftarInteger
s Anda memiliki masalahIni adalah
O(n)
algoritma yang baik (kecuali Anda melakukan beberapa solusi multi-threaded di mana Anda memecah daftar menjadi beberapa sublists, tapi saya tidak berpikir itu yang Anda minta).Gunakan saja
StringBuilder
seperti di bawah ini:The
StringBuilder
akan jauh lebih cepat daripada Rangkaian string karena Anda tidak akan kembali instantiatingString
objek pada setiap rangkaian.sumber
Jika Anda kebetulan menggunakan Android dan Anda belum menggunakan Jack (mis. Karena masih kurang dukungan untuk Instant Run), dan jika Anda ingin lebih mengontrol format string yang dihasilkan (mis. Anda ingin menggunakan karakter baris baru sebagai pembagi elemen), dan kebetulan menggunakan / ingin menggunakan pustaka StreamSupport (untuk menggunakan stream di Java 7 atau versi sebelumnya dari kompiler), Anda dapat menggunakan sesuatu seperti ini (saya meletakkan metode ini di kelas ListUtils saya):
Dan tentu saja, pastikan untuk mengimplementasikan toString () pada kelas objek daftar Anda.
sumber
reduce
sangat tidak efisien untuk penggabungan String. Anda harus melakukannya dengan cara Java 8return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))
yang digunakan secara internalStringJoiner
. Tidak ada alasan Anda tidak dapat melakukan ini dengan dukungan streams juga.Optional#get
) jika melewati daftar kosong.Jika Anda tidak ingin yang terakhir setelah elemen terakhir, Anda harus menggunakan indeks untuk memeriksa, tetapi ingat bahwa ini hanya "berfungsi" (yaitu O (n)) ketika daftar mengimplementasikan RandomAccess.
sumber
Kode di bawah ini dapat membantu Anda,
Keluaran:
sumber
Mungkin bukan cara terbaik, tapi cara yang elegan.
Arrays.deepToString (Arrays.asList ("Test", "Test2")
Keluaran
[Tes, Test2]
sumber
Apakah yang berikut ini ada gunanya:
sumber
Jika Anda menggunakan Eclipse Collections , Anda dapat menggunakan
makeString()
metode ini.Jika Anda dapat mengonversi
ArrayList
keFastList
, Anda dapat menyingkirkan adaptor.Catatan: Saya pengendara untuk Eclipse Collections.
sumber
Anda meneruskan ke
new StringJoiner
urutan char yang ingin Anda gunakan sebagai pemisah. Jika Anda ingin melakukan CSV:new StringJoiner(", ");
sumber
Dalam satu Baris: Dari [12,0,1,78,12] menjadi 12 0 1 78 12
sumber
Untuk memisahkan menggunakan tab daripada menggunakan println Anda dapat menggunakan print
sumber
Saya melihat beberapa contoh yang tergantung pada sumber daya tambahan, tetapi sepertinya ini akan menjadi solusi paling sederhana: (yang saya gunakan dalam proyek saya sendiri) yang pada dasarnya hanya mengkonversi dari ArrayList ke Array dan kemudian ke Daftar .
sumber
Ini adalah percakapan yang cukup lama sekarang dan apache commons sekarang menggunakan StringBuilder secara internal: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line. 3045
Ini akan seperti yang kita ketahui meningkatkan kinerja, tetapi jika kinerja sangat penting maka metode yang digunakan mungkin agak tidak efisien. Sedangkan antarmuka fleksibel dan akan memungkinkan untuk perilaku yang konsisten di berbagai jenis Koleksi itu agak tidak efisien untuk Daftar, yang merupakan jenis Koleksi dalam pertanyaan awal.
Saya mendasarkan ini di bahwa kita mengeluarkan beberapa overhead yang kita akan hindari dengan hanya mengulangi elemen-elemen dalam tradisional untuk loop. Sebaliknya ada beberapa hal tambahan yang terjadi di belakang layar memeriksa modifikasi bersamaan, panggilan metode dll. Peningkatan loop akan di sisi lain menghasilkan overhead yang sama karena iterator digunakan pada objek Iterable (Daftar).
sumber
Anda dapat menggunakan Regex untuk ini. Ini singkat seperti yang didapat
sumber
Bagaimana dengan fungsi ini:
ini bekerja untuk semua jenis koleksi ...
sumber