Apakah ada cara mudah untuk memasang String di Jawa?
Sepertinya ada sesuatu yang harus ada di beberapa StringUtil-like API, tapi saya tidak dapat menemukan apa pun yang melakukan ini.
Apakah ada cara mudah untuk memasang String di Jawa?
Sepertinya ada sesuatu yang harus ada di beberapa StringUtil-like API, tapi saya tidak dapat menemukan apa pun yang melakukan ini.
Jawaban:
Apache StringUtils
memiliki beberapa metode: leftPad
, rightPad
, center
dan repeat
.
Tetapi harap dicatat bahwa - seperti yang telah disebutkan dan didemonstrasikan dalam jawaban ini - String.format()
dan Formatter
kelas - kelas di JDK adalah pilihan yang lebih baik. Gunakan mereka di atas kode milik bersama.
Sejak Java 1.5, String.format()
dapat digunakan untuk kiri / kanan pad string yang diberikan.
public static String padRight(String s, int n) {
return String.format("%-" + n + "s", s);
}
public static String padLeft(String s, int n) {
return String.format("%" + n + "s", s);
}
...
public static void main(String args[]) throws Exception {
System.out.println(padRight("Howto", 20) + "*");
System.out.println(padLeft("Howto", 20) + "*");
}
Dan hasilnya adalah:
Howto *
Howto*
1$
? @leo telah membuat jawaban yang sangat mirip yang tidak digunakan 1$
dan ternyata memiliki efek yang sama. Apakah itu membuat perbedaan?
Padding hingga 10 karakter:
String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');
keluaran:
*******foo
bar*******
longer*than*10*chars
Tampilkan '*' untuk karakter kata sandi:
String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');
output memiliki panjang yang sama dengan string kata sandi:
secret123
*********
.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:
Strings.padStart("string", 10, ' ');
Strings.padEnd("string", 10, ' ');
Sesuatu yang sederhana:
Nilai harus berupa string. mengubahnya menjadi string, jika tidak. Suka "" + 123
atauInteger.toString(123)
// let's assume value holds the String we want to pad
String value = "123";
Substring mulai dari nilai indeks panjang char sampai panjang akhir dari padded:
String padded="00000000".substring(value.length()) + value;
// now padded is "00000123"
Lebih tepat
pad kanan:
String padded = value + ("ABCDEFGH".substring(value.length()));
// now padded is "123DEFGH"
pad kiri:
String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;
// now padded is "ABCDE123"
Lihatlah org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.
Tetapi algoritma ini sangat sederhana (pad hingga chars ukuran):
public String pad(String str, int size, char padChar)
{
StringBuffer padded = new StringBuffer(str);
while (padded.length() < size)
{
padded.append(padChar);
}
return padded.toString();
}
Selain Apache Commons, lihat juga String.format
mana yang harus bisa merawat lapisan sederhana (misalnya dengan spasi).
public static String LPad(String str, Integer length, char car) {
return (str + String.format("%" + length + "s", "").replace(" ", String.valueOf(car))).substring(0, length);
}
public static String RPad(String str, Integer length, char car) {
return (String.format("%" + length + "s", "").replace(" ", String.valueOf(car)) + str).substring(str.length(), length + str.length());
}
LPad("Hi", 10, 'R') //gives "RRRRRRRRHi"
RPad("Hi", 10, 'R') //gives "HiRRRRRRRR"
RPad("Hi", 10, ' ') //gives "Hi "
RPad("Hi", 1, ' ') //gives "H"
//etc...
str
, jadi ini benar.
(length - str.length())
adanya 0
? Formatter melempar FormatFlagsConversionMismatchException
kapan %0s
adalah string format.
Saya butuh waktu beberapa saat untuk mencari tahu. Kunci sebenarnya adalah membaca dokumentasi Formatter itu.
// Get your data from wherever.
final byte[] data = getData();
// Get the digest engine.
final MessageDigest md5= MessageDigest.getInstance("MD5");
// Send your data through it.
md5.update(data);
// Parse the data as a positive BigInteger.
final BigInteger digest = new BigInteger(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);
Saya tahu utas ini agak tua dan pertanyaan awal adalah untuk solusi mudah tetapi jika itu seharusnya sangat cepat, Anda harus menggunakan array char.
public static String pad(String str, int size, char padChar)
{
if (str.length() < size)
{
char[] temp = new char[size];
int i = 0;
while (i < str.length())
{
temp[i] = str.charAt(i);
i++;
}
while (i < size)
{
temp[i] = padChar;
i++;
}
str = new String(temp);
}
return str;
}
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
StringBuffer padded = new StringBuffer(str);
dengan
StringBuffer padded = new StringBuffer(pad);
padded.append(value);
akan mencegah buffer internal sb tumbuh.
StringBuffer
tidak dapat diakses oleh banyak utas sekaligus (yang dalam hal ini benar), Anda harus menggunakan StringBuilder
(dalam JDK1.5 +) untuk menghindari overhead sinkronisasi.
Berikut cara lain untuk menyamping ke kanan:
// put the number of spaces, or any character you like, in your paddedString
String paddedString = "--------------------";
String myStringToBePadded = "I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());
//result:
myStringToBePadded = "I like donuts-------";
Sejak Java 11, String.repeat (int) dapat digunakan untuk kiri / kanan pad string yang diberikan.
System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));
Keluaran:
*****apple
apple*****
Anda dapat mengurangi overhead per panggilan dengan mempertahankan data padding, daripada membangunnya kembali setiap kali:
public class RightPadder {
private int length;
private String padding;
public RightPadder(int length, String pad) {
this.length = length;
StringBuilder sb = new StringBuilder(pad);
while (sb.length() < length) {
sb.append(sb);
}
padding = sb.toString();
}
public String pad(String s) {
return (s.length() < length ? s + padding : s).substring(0, length);
}
}
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! ;-)
Menemukan ini di Dzone
Pad dengan nol:
String.format("|%020d|", 93); // prints: |00000000000000000093|
Anda dapat menggunakan metode built in StringBuilder append () dan insert (), untuk mengisi panjang string variabel:
AbstractStringBuilder append(CharSequence s, int start, int end) ;
Sebagai contoh:
private static final String MAX_STRING = " "; //20 spaces
Set<StringBuilder> set= new HashSet<StringBuilder>();
set.add(new StringBuilder("12345678"));
set.add(new StringBuilder("123456789"));
set.add(new StringBuilder("1234567811"));
set.add(new StringBuilder("12345678123"));
set.add(new StringBuilder("1234567812234"));
set.add(new StringBuilder("1234567812222"));
set.add(new StringBuilder("12345678122334"));
for(StringBuilder padMe: set)
padMe.append(MAX_STRING, padMe.length(), MAX_STRING.length());
Ini bekerja:
"".format("%1$-" + 9 + "s", "XXX").replaceAll(" ", "0")
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 ...
static
metode ini String.format(…)
alih-alih menyalahgunakan string kosong. Menyimpan empat karakter dalam kode sumber tentunya tidak sebanding dengan hilangnya keterbacaan.
public static String padLeft(String in, int size, char padChar) {
if (in.length() <= size) {
char[] temp = new char[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++;
}
return new String(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 StringUtils
Apache Commons tetapi menggunakan cara ini:
StringUtils.defaultString(StringUtils.leftPad(myString, 1))
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 null@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 .
public static String pad(String source, char fill, int length, boolean right){
if(source.length() > length) return source;
char[] out = new char[length];
if(right){
System.arraycopy(source.toCharArray(), 0, out, 0, source.length());
Arrays.fill(out, source.length(), length, fill);
}else{
int sourceOffset = length - source.length();
System.arraycopy(source.toCharArray(), 0, out, sourceOffset, source.length());
Arrays.fill(out, 0, sourceOffset, fill);
}
return new String(out);
}
Metode pengujian sederhana:
public static void 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 long for your own good, buddy
getChars
untuk membiarkan String
salinan isinya langsung ke dalam out
array, 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 fill
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.]
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.
public static char[] lpad(char[] pStringChar, int pTotalLength, char pPad) {
if (pStringChar.length < pTotalLength) {
char[] retChar = new char[pTotalLength];
int padIdx = pTotalLength - pStringChar.length;
Arrays.fill(retChar, 0, padIdx, pPad);
System.arraycopy(pStringChar, 0, retChar, padIdx, pStringChar.length);
return retChar;
} else {
return pStringChar;
}
}
Gunakan fungsi ini.
private String leftPadding(String word, int length, char ch) {
return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}
Cara Penggunaan?
leftPadding(month, 2, '0');
output: 01 02 03 04 .. 11 12
Banyak orang memiliki beberapa teknik yang sangat menarik tetapi saya ingin membuatnya tetap sederhana jadi saya ikuti ini:
public static String padRight(String s, int n, char padding){
StringBuilder builder = new StringBuilder(s.length() + n);
builder.append(s);
for(int i = 0; i < n; i++){
builder.append(padding);
}
return builder.toString();
}
public static String padLeft(String s, int n, char padding) {
StringBuilder builder = new StringBuilder(s.length() + n);
for(int i = 0; i < n; i++){
builder.append(Character.toString(padding));
}
return builder.append(s).toString();
}
public static String pad(String s, int n, char padding){
StringBuilder pad = new StringBuilder(s.length() + n * 2);
StringBuilder value = new StringBuilder(n);
for(int i = 0; i < n; i++){
pad.append(padding);
}
return value.append(pad).append(s).append(pad).toString();
}
Solusi sederhana tanpa API adalah sebagai berikut:
public String pad(String num, int len){
if(len-num.length() <=0) return num;
StringBuffer sb = new StringBuffer();
for(i=0; i<(len-num.length()); i++){
sb.append("0");
}
sb.append(num);
return sb.toString();
}
Oneliners Java, tidak ada perpustakaan mewah.
// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"
Pad Kiri, jangan batasi
result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"
Pad Kanan, jangan membatasi
result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"
Pad Kiri, batas ke panjang pad
result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"
Pad Kanan, batasi panjang pad
result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"
Bagaimana kalau menggunakan rekursi? Solusi yang diberikan di bawah ini kompatibel dengan semua versi JDK dan tidak ada perpustakaan eksternal yang diperlukan :)
private static String addPadding(final String str, final int desiredLength, final String 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));
Padding contoh dalam Jambu Biji:
Padding contoh di Apache Commons:
Padding contoh dalam JDK:
Solusi sederhana adalah:
package nl;
public class Padder {
public static void main(String[] args) {
String s = "123" ;
System.out.println("#"+(" " + s).substring(s.length())+"#");
}
}