Pada masalah fungsi apache vs string formatter ada sedikit keraguan bahwa fungsi apache lebih jelas dan mudah dibaca. Membungkus formatter dengan nama fungsi tidak ideal.
Tetapi harap dicatat bahwa - seperti yang telah disebutkan dan didemonstrasikan dalam jawaban ini - String.format()dan Formatterkelas - kelas di JDK adalah pilihan yang lebih baik. Gunakan mereka di atas kode milik bersama.
java.util.Formatter (dan String.format ()) melakukan ini. Selalu lebih suka JDK daripada pustaka eksternal jika versi JDK melakukan pekerjaan (yang dilakukannya).
@Jonik maukah kamu menuliskan beberapa alasanmu? API terlihat hampir sama.
glen3b
3
@ glen3b: Untuk utilitas perorangan, seperti helper padding string ini, benar-benar tidak ada bedanya lib mana yang digunakan. Yang mengatakan, Guava secara keseluruhan lebih modern, lebih bersih dan lebih baik didokumentasikan lib daripada rekan-rekannya di berbagai proyek Apache Commons (Commons Lang, Commons Collections, Commons IO, dll). Ini juga dibangun oleh orang-orang yang benar-benar pintar (Kevin Bourrillion et al), banyak dari mereka yang aktif di SO . Saya sendiri akhirnya mengganti berbagai Apache Commons libs hanya dengan Jambu tahun yang lalu, dan tidak menyesal.
@ Nullw0rm, jika Anda merujuk ke rgagnon.com, ketahuilah bahwa RealHowTo adalah penulis rgagnon.com juga, jadi dia akan mengkredit dirinya sendiri ...
Colin Pickard
3
setidaknya di JVM saya, "#" tidak berfungsi, "-" baik-baik saja. (Hapus saja #). Ini mungkin konsisten dengan dokumentasi formatter, saya tidak tahu; ia mengatakan "'#' '\ u0023' Membutuhkan output menggunakan formulir alternatif. Definisi formulir ditentukan oleh konversi."
gatoatigrado
6
Terima kasih atas jawabannya. Tapi saya ragu, untuk apa 1$? @leo telah membuat jawaban yang sangat mirip yang tidak digunakan 1$dan ternyata memiliki efek yang sama. Apakah itu membuat perbedaan?
Fabrício Matté
257
Padding hingga 10 karakter:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Asalkan kita semua ingat untuk tidak melewati string dengan spasi ...: D
leviathanbadger
4
Saya dengan @ aboveyou00 - ini adalah solusi menghebohkan untuk string dengan spasi, termasuk contoh yang diberikan oleh leo. Solusi untuk melapisi string di sebelah kiri atau kanan tidak boleh mengubah string input seperti yang muncul di output, kecuali padding string input asli menyebabkannya melebihi panjang bantalan yang ditentukan.
Brian Warshaw
3
Akui masalah ruang angkasa. .replace(' ', '*')lebih dimaksudkan untuk menunjukkan efek padding. Ekspresi penyembunyian kata sandi tidak memiliki masalah ini ... Untuk jawaban yang lebih baik tentang menyesuaikan string padding kiri dan kanan menggunakan fitur Java asli, lihat jawaban saya yang lain.
leo
Jika string hanya berisi spasi tunggal dan Anda ingin membalut dengan karakter yang berbeda, Anda dapat menggunakan regex ganti dengan tampilan di belakang / depan: String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")atauString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Perhatikan: Anda nama fungsi terbalik; jika Anda menjalankannya Anda akan melihat.
kebiruan
ditambah jika str asli berisi spasi maka ini tidak berfungsi
Steven Shaw
@ SvenvenShaw Jika saya tidak salah, ganti tidak menargetkan yang asli str, jadi ini benar.
mafu
3
Dengan konvensi, Anda tidak boleh menggunakan huruf kapital untuk nama fungsi.
principal-ideal-domain
Apakah ada persyaratan yang hilang untuk mengembalikan string seperti apa (length - str.length())adanya 0? Formatter melempar FormatFlagsConversionMismatchExceptionkapan %0sadalah string format.
Devin Walters
7
Saya butuh waktu beberapa saat untuk mencari tahu. Kunci sebenarnya adalah membaca dokumentasi Formatter itu.
// Get your data from wherever.finalbyte[] data = getData();// Get the digest engine.finalMessageDigest md5=MessageDigest.getInstance("MD5");// Send your data through it.
md5.update(data);// Parse the data as a positive BigInteger.finalBigInteger digest =newBigInteger(1,md5.digest());// Pad the digest with blanks, 32 wide.String hex =String.format(// See: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html// Format: %[argument_index$][flags][width]conversion// Conversion: 'x', 'X' integral The result is formatted as a hexadecimal integer"%1$32x",
digest
);// Replace the blank padding with 0s.
hex = hex.replace(" ","0");System.out.println(hex);
Mengapa membuat akhirnya begitu rumit? Anda bisa saja melakukan String hex = String.format ("% 032x", digest); dan memiliki hasil yang sama persis, hanya tanpa penggantian yang tidak perlu () dan harus menggunakan $ untuk mengakses variabel tertentu (setelah itu hanya ada satu.)
ArtOfWarfare
Titik adil @ArtOfWarfare. Seseorang awalnya meminta nilai hex padding dalam pertanyaan lain, saya melihat bahwa saya memiliki tautan ke dokumentasi formatter. Ini rumit untuk kelengkapan.
Nthalk
6
Saya tahu utas ini agak tua dan pertanyaan awal adalah untuk solusi mudah tetapi jika itu seharusnya sangat cepat, Anda harus menggunakan array char.
Jika StringBuffertidak dapat diakses oleh banyak utas sekaligus (yang dalam hal ini benar), Anda harus menggunakan StringBuilder(dalam JDK1.5 +) untuk menghindari overhead sinkronisasi.
glen3b
5
Berikut cara lain untuk menyamping ke kanan:
// put the number of spaces, or any character you like, in your paddedStringString paddedString ="--------------------";String myStringToBePadded ="I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());//result:
myStringToBePadded ="I like donuts-------";
Sebagai alternatif, Anda bisa menjadikan panjang parameter sebagai pad(...)metode. Dalam hal itu lakukan penyesuaian padding tersembunyi dalam metode itu daripada di konstruktor.
(Petunjuk: Untuk kredit ekstra, buat itu aman dari thread! ;-)
Itu aman utas, kecuali untuk publikasi yang tidak aman (menjadikan bidang Anda final, tentu saja). Saya pikir kinerja dapat ditingkatkan dengan melakukan substring sebelum + yang harus diganti dengan concat (anehnya).
Ini akan mengisi String XXX Anda hingga 9 Chars dengan spasi putih. Setelah itu semua spasi putih akan diganti dengan 0. Anda dapat mengubah spasi putih dan 0 untuk apa pun yang Anda inginkan ...
Anda harus menggunakan staticmetode ini String.format(…)alih-alih menyalahgunakan string kosong. Menyimpan empat karakter dalam kode sumber tentunya tidak sebanding dengan hilangnya keterbacaan.
Holger
2
publicstaticString padLeft(String in,int size,char padChar){if(in.length()<= size){char[] temp =newchar[size];/* Llenado Array con el padChar*/for(int i =0;i<size;i++){
temp[i]= padChar;}int posIniTemp = size-in.length();for(int i=0;i<in.length();i++){
temp[posIniTemp]=in.charAt(i);
posIniTemp++;}returnnewString(temp);}return"";}
Mari saya tinggalkan jawaban untuk beberapa kasus yang harus Anda beri bantalan kiri / kanan (atau string atau spasi awalan / akhiran) sebelum Anda menyambung ke string lain dan Anda tidak ingin menguji panjang atau kondisi apa pun.
Sama dengan jawaban yang dipilih, saya lebih suka StringUtilsApache Commons tetapi menggunakan cara ini:
@ck 's dan @Marlon Tarak jawaban adalah satu-satunya yang menggunakan char[], yang untuk aplikasi yang memiliki beberapa panggilan untuk metode padding per detik adalah pendekatan terbaik. Namun, mereka tidak memanfaatkan optimasi manipulasi array dan sedikit ditimpa sesuai selera saya; ini bisa dilakukan tanpa loop sama sekali .
publicstaticvoid main(String... args){System.out.println("012345678901234567890123456789");System.out.println(pad("cats",' ',30,true));System.out.println(pad("cats",' ',30,false));System.out.println(pad("cats",' ',20,false));System.out.println(pad("cats",'$',30,true));System.out.println(pad("too long for your own good, buddy",'#',30,true));}
Output:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Anda dapat menggunakan getCharsuntuk membiarkan Stringsalinan isinya langsung ke dalam outarray, alih-alih memanggil source.toCharArray(), diikuti oleh System.arraycopy. Saya bahkan akan mempertimbangkan untuk menyederhanakan implementasi menjadi char[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);; sementara ini sepertinya fillakan melakukan lebih banyak pekerjaan, itu benar-benar memungkinkan JVM untuk menghilangkan pengisian nol default.
Holger
1
java.util.Formatterakan melakukan padding kiri dan kanan. Tidak perlu untuk dependensi pihak ketiga yang aneh (Anda ingin menambahkannya untuk sesuatu yang sepele).
[Saya telah meninggalkan detailnya dan menjadikan posting ini 'komunitas wiki' karena ini bukan sesuatu yang saya butuhkan.]
Saya tidak setuju. Dalam setiap proyek Java yang lebih besar, Anda biasanya akan melakukan banyak manipulasi String, sehingga peningkatan keterbacaan dan penghindaran kesalahan sangat layak menggunakan Apache Commons Lang. Anda semua tahu kode seperti someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), yang dapat dengan mudah dihindari dengan StringUtils.
Bananeweizen
1
Semua operasi string biasanya harus sangat efisien - terutama jika Anda bekerja dengan set data yang besar. Saya menginginkan sesuatu yang cepat dan fleksibel, mirip dengan apa yang akan Anda dapatkan dalam perintah pad plsql. Juga, saya tidak ingin memasukkan lib besar hanya untuk satu hal kecil. Dengan pertimbangan ini tidak ada solusi yang memuaskan. Ini adalah solusi yang saya buat, yang memiliki hasil penilaian terbaik, jika ada yang bisa meningkatkannya, silakan tambahkan komentar Anda.
perhatikan itu disebut dengan String.toCharArray () dan hasilnya dapat dikonversi ke String dengan hasil String ((char []) baru). Alasannya adalah, jika Anda menerapkan beberapa operasi, Anda dapat melakukan semuanya pada char [] dan tidak terus mengonversi antar format - di belakang layar, String disimpan sebagai char []. Jika operasi ini termasuk dalam kelas String itu sendiri, itu akan menjadi dua kali lebih efisien - kecepatan dan memori bijaksana.
Bagaimana kalau menggunakan rekursi? Solusi yang diberikan di bawah ini kompatibel dengan semua versi JDK dan tidak ada perpustakaan eksternal yang diperlukan :)
privatestaticString addPadding(finalString str,finalint desiredLength,finalString padBy){String result = str;if(str.length()>= desiredLength){return result;}else{
result += padBy;return addPadding(result, desiredLength, padBy);}}
CATATAN : Solusi ini akan menambahkan padding, dengan sedikit perubahan Anda dapat awalan nilai pad.
Inilah versi paralelnya bagi Anda yang memiliki string sangat panjang :-)
int width =100;String s ="129018";CharSequence padded =IntStream.range(0,width).parallel().map(i->i-(width-s.length())).map(i->i<0?'0':s.charAt(i)).collect(StringBuilder::new,(sb,c)-> sb.append((char)c),(sb1,sb2)->sb1.append(sb2));
Jawaban:
Apache
StringUtils
memiliki beberapa metode:leftPad
,rightPad
,center
danrepeat
.Tetapi harap dicatat bahwa - seperti yang telah disebutkan dan didemonstrasikan dalam jawaban ini -
String.format()
danFormatter
kelas - kelas di JDK adalah pilihan yang lebih baik. Gunakan mereka di atas kode milik bersama.sumber
Sejak Java 1.5,
String.format()
dapat digunakan untuk kiri / kanan pad string yang diberikan.Dan hasilnya adalah:
sumber
1$
? @leo telah membuat jawaban yang sangat mirip yang tidak digunakan1$
dan ternyata memiliki efek yang sama. Apakah itu membuat perbedaan?Padding hingga 10 karakter:
keluaran:
Tampilkan '*' untuk karakter kata sandi:
output memiliki panjang yang sama dengan string kata sandi:
sumber
.replace(' ', '*')
lebih dimaksudkan untuk menunjukkan efek padding. Ekspresi penyembunyian kata sandi tidak memiliki masalah ini ... Untuk jawaban yang lebih baik tentang menyesuaikan string padding kiri dan kanan menggunakan fitur Java asli, lihat jawaban saya yang lain.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
atauString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Di Jambu , ini mudah:
sumber
Sesuatu yang sederhana:
Nilai harus berupa string. mengubahnya menjadi string, jika tidak. Suka
"" + 123
atauInteger.toString(123)
Substring mulai dari nilai indeks panjang char sampai panjang akhir dari padded:
Lebih tepat
pad kanan:
pad kiri:
sumber
Lihatlah
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Tetapi algoritma ini sangat sederhana (pad hingga chars ukuran):
sumber
Selain Apache Commons, lihat juga
String.format
mana yang harus bisa merawat lapisan sederhana (misalnya dengan spasi).sumber
sumber
str
, jadi ini benar.(length - str.length())
adanya0
? Formatter melemparFormatFlagsConversionMismatchException
kapan%0s
adalah string format.Saya butuh waktu beberapa saat untuk mencari tahu. Kunci sebenarnya adalah membaca dokumentasi Formatter itu.
sumber
Saya tahu utas ini agak tua dan pertanyaan awal adalah untuk solusi mudah tetapi jika itu seharusnya sangat cepat, Anda harus menggunakan array char.
solusi formatter tidak optimal. hanya membangun string format membuat 2 string baru.
solusi apache dapat ditingkatkan dengan menginisialisasi sb dengan ukuran target jadi ganti di bawah ini
dengan
akan mencegah buffer internal sb tumbuh.
sumber
StringBuffer
tidak dapat diakses oleh banyak utas sekaligus (yang dalam hal ini benar), Anda harus menggunakanStringBuilder
(dalam JDK1.5 +) untuk menghindari overhead sinkronisasi.Berikut cara lain untuk menyamping ke kanan:
sumber
Sejak Java 11, String.repeat (int) dapat digunakan untuk kiri / kanan pad string yang diberikan.
Keluaran:
sumber
Anda dapat mengurangi overhead per panggilan dengan mempertahankan data padding, daripada membangunnya kembali setiap kali:
Sebagai alternatif, Anda bisa menjadikan panjang parameter sebagai
pad(...)
metode. Dalam hal itu lakukan penyesuaian padding tersembunyi dalam metode itu daripada di konstruktor.(Petunjuk: Untuk kredit ekstra, buat itu aman dari thread! ;-)
sumber
Menemukan ini di Dzone
Pad dengan nol:
sumber
Anda dapat menggunakan metode built in StringBuilder append () dan insert (), untuk mengisi panjang string variabel:
Sebagai contoh:
sumber
Ini bekerja:
Ini akan mengisi String XXX Anda hingga 9 Chars dengan spasi putih. Setelah itu semua spasi putih akan diganti dengan 0. Anda dapat mengubah spasi putih dan 0 untuk apa pun yang Anda inginkan ...
sumber
static
metode iniString.format(…)
alih-alih menyalahgunakan string kosong. Menyimpan empat karakter dalam kode sumber tentunya tidak sebanding dengan hilangnya keterbacaan.sumber
Mari saya tinggalkan jawaban untuk beberapa kasus yang harus Anda beri bantalan kiri / kanan (atau string atau spasi awalan / akhiran) sebelum Anda menyambung ke string lain dan Anda tidak ingin menguji panjang atau kondisi apa pun.
Sama dengan jawaban yang dipilih, saya lebih suka
StringUtils
Apache Commons tetapi menggunakan cara ini:Menjelaskan:
myString
: input string I, bisa nolStringUtils.leftPad(myString, 1)
: jika string adalah nol, pernyataan ini akan mengembalikan nol jugadefaultString
untuk memberikan string kosong untuk mencegah concatenate nullsumber
@ck 's dan @Marlon Tarak jawaban adalah satu-satunya yang menggunakan
char[]
, yang untuk aplikasi yang memiliki beberapa panggilan untuk metode padding per detik adalah pendekatan terbaik. Namun, mereka tidak memanfaatkan optimasi manipulasi array dan sedikit ditimpa sesuai selera saya; ini bisa dilakukan tanpa loop sama sekali .Metode pengujian sederhana:
Output:
sumber
getChars
untuk membiarkanString
salinan isinya langsung ke dalamout
array, alih-alih memanggilsource.toCharArray()
, diikuti olehSystem.arraycopy
. Saya bahkan akan mempertimbangkan untuk menyederhanakan implementasi menjadichar[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);
; sementara ini sepertinyafill
akan melakukan lebih banyak pekerjaan, itu benar-benar memungkinkan JVM untuk menghilangkan pengisian nol default.java.util.Formatter
akan melakukan padding kiri dan kanan. Tidak perlu untuk dependensi pihak ketiga yang aneh (Anda ingin menambahkannya untuk sesuatu yang sepele).[Saya telah meninggalkan detailnya dan menjadikan posting ini 'komunitas wiki' karena ini bukan sesuatu yang saya butuhkan.]
sumber
Semua operasi string biasanya harus sangat efisien - terutama jika Anda bekerja dengan set data yang besar. Saya menginginkan sesuatu yang cepat dan fleksibel, mirip dengan apa yang akan Anda dapatkan dalam perintah pad plsql. Juga, saya tidak ingin memasukkan lib besar hanya untuk satu hal kecil. Dengan pertimbangan ini tidak ada solusi yang memuaskan. Ini adalah solusi yang saya buat, yang memiliki hasil penilaian terbaik, jika ada yang bisa meningkatkannya, silakan tambahkan komentar Anda.
sumber
Gunakan fungsi ini.
Cara Penggunaan?
output: 01 02 03 04 .. 11 12
sumber
Banyak orang memiliki beberapa teknik yang sangat menarik tetapi saya ingin membuatnya tetap sederhana jadi saya ikuti ini:
sumber
Solusi sederhana tanpa API adalah sebagai berikut:
sumber
Oneliners Java, tidak ada perpustakaan mewah.
Pad Kiri, jangan batasi
Pad Kanan, jangan membatasi
Pad Kiri, batas ke panjang pad
Pad Kanan, batasi panjang pad
sumber
Bagaimana kalau menggunakan rekursi? Solusi yang diberikan di bawah ini kompatibel dengan semua versi JDK dan tidak ada perpustakaan eksternal yang diperlukan :)
CATATAN : Solusi ini akan menambahkan padding, dengan sedikit perubahan Anda dapat awalan nilai pad.
sumber
Inilah versi paralelnya bagi Anda yang memiliki string sangat panjang :-)
sumber
Padding contoh dalam Jambu Biji:
Padding contoh di Apache Commons:
Padding contoh dalam JDK:
sumber
Solusi sederhana adalah:
sumber
Bagaimana ini
String "hello" dan padding yang dibutuhkan adalah 15 dengan "0" pad kiri
sumber