In Bezug auf die Apache-Funktion im Vergleich zum String-Formatierer besteht kaum ein Zweifel daran, dass die Apache-Funktion klarer und leichter zu lesen ist. Das Umschließen des Formatierers in Funktionsnamen ist nicht ideal.
Beachten Sie jedoch, dass - wie andere in dieser Antwort erwähnt und demonstriert haben - String.format()und die FormatterKlassen im JDK bessere Optionen sind. Verwenden Sie sie über den Commons-Code.
java.util.Formatter (und String.format ()) tun dies. Ziehen Sie das JDK immer einer externen Bibliothek vor, wenn die JDK-Version den Job erledigt (was sie auch tut).
@ Jonik Möchten Sie einige Ihrer Gründe auflisten? Die APIs sehen ziemlich gleich aus.
Glen3B
3
@ glen3b: Für ein einzelnes Dienstprogramm, wie diese Hilfsprogramme zum Auffüllen von Zeichenfolgen, spielt es keine Rolle, welche Bibliothek verwendet werden soll. Trotzdem ist Guava insgesamt eine modernere, sauberere und besser dokumentierte Bibliothek als ihre Kollegen in verschiedenen Apache Commons-Projekten (Commons Lang, Commons Collections, Commons IO usw.). Es wurde auch von wirklich klugen Leuten (Kevin Bourrillion et al.) Gebaut, von denen viele bei SO aktiv sind . Ich selbst habe vor Jahren die verschiedenen Apache Commons-Bibliotheken durch Guava ersetzt und habe es nicht bereut.
@ Nullw0rm, wenn Sie sich auf rgagnon.com beziehen, beachten Sie, dass RealHowTo auch der Autor von rgagnon.com ist, also würde er sich selbst gutschreiben ...
Colin Pickard
3
Zumindest auf meiner JVM funktioniert das "#" nicht, das "-" ist in Ordnung. (Löschen Sie einfach das #). Dies kann mit der Formatierungsdokumentation übereinstimmen, ich weiß nicht; Es heißt "'#' '\ u0023'. Für die Ausgabe muss ein alternatives Formular verwendet werden. Die Definition des Formulars wird durch die Konvertierung angegeben."
Gatoatigrado
6
Danke für die tolle Antwort. Ich habe jedoch Zweifel, wofür ist das 1$? @leo hat eine sehr ähnliche Antwort gegeben, die nicht verwendet wird 1$und anscheinend den gleichen Effekt hat. Macht es einen Unterschied?
Fabrício Matté
257
Auffüllen auf 10 Zeichen:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Nur solange wir uns alle daran erinnern, keine Zeichenfolge mit Leerzeichen
einzugeben
4
Ich bin bei @ Aboveyou00 - dies ist eine schreckliche Lösung für Zeichenfolgen mit Leerzeichen, einschließlich des Beispiels von Leo. Eine Lösung zum Auffüllen einer Zeichenfolge links oder rechts sollte die Eingabezeichenfolge, wie sie in der Ausgabe angezeigt wird, nicht ändern, es sei denn, die ursprüngliche Auffüllung der Eingabezeichenfolge bewirkt, dass sie die angegebene Auffülllänge überschreitet.
Brian Warshaw
3
Bestätigen Sie das Platzproblem. .replace(' ', '*')sollte eher die Wirkung der Polsterung zeigen. Der Ausdruck zum Ausblenden von Passwörtern hat dieses Problem ohnehin nicht ... Eine bessere Antwort zum Anpassen der linken und rechten Füllzeichenfolge mithilfe der nativen Java-Funktion finden Sie in meiner anderen Antwort.
Leo
Wenn die Zeichenfolge nur einzelne Leerzeichen enthält und Sie mit unterschiedlichen Zeichen String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Achten Sie darauf: Sie haben Funktionsnamen invertiert; Wenn Sie es ausführen, werden Sie sehen.
bläulich
Plus, wenn die ursprüngliche str Leerzeichen enthält, dann funktioniert dies nicht
Steven Shaw
@StevenShaw Wenn ich mich nicht irre, zielt der Ersatz nicht auf das Original ab str, daher ist dies korrekt.
Mafu
3
Konventionell sollten Sie für Funktionsnamen keinen Großbuchstaben verwenden.
Principal-Ideal-Domain
Gibt es eine fehlende Bedingung für die Rückgabe der Zeichenfolge wie sie (length - str.length())ist 0? Der Formatierer gibt ein FormatFlagsConversionMismatchExceptionWann aus, %0sdas die Formatzeichenfolge ist.
Devin Walters
7
Ich brauchte eine Weile, um das herauszufinden. Der eigentliche Schlüssel ist das Lesen dieser Formatter-Dokumentation.
// 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);
Warum das Ende so kompliziert machen? Sie hätten einfach String hex = String.format ("% 032x", Digest) ausführen können; und hatte genau die gleichen Ergebnisse, nur ohne unnötiges Ersetzen () und mit dem $ auf bestimmte Variablen zugreifen zu müssen (es gibt schließlich nur eine.)
ArtOfWarfare
@ArtOfWarfare fair point. Jemand fragte ursprünglich nach dem Auffüllen von Hex-Werten in einer anderen Frage. Ich sah, dass ich einen Link zur Formatierungsdokumentation hatte. Der Vollständigkeit halber ist es kompliziert.
Nthalk
6
Ich weiß, dass dieser Thread etwas alt ist und die ursprüngliche Frage war für eine einfache Lösung, aber wenn es wirklich schnell sein soll, sollten Sie ein char-Array verwenden.
Wenn StringBuffernicht mehrere Threads gleichzeitig auf das StringBuilderzugreifen können (was in diesem Fall zutrifft), sollten Sie ein (in JDK1.5 +) verwenden, um den Aufwand für die Synchronisierung zu vermeiden.
Glen3B
5
Hier ist eine andere Möglichkeit, nach rechts zu tippen:
// 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-------";
Alternativ können Sie die Ergebnislänge zu einem Parameter für die pad(...)Methode machen. Nehmen Sie in diesem Fall die Anpassung der ausgeblendeten Auffüllung in dieser Methode anstelle im Konstruktor vor.
(Hinweis: Für zusätzliche Gutschrift machen Sie es threadsicher! ;-)
Das ist threadsicher, außer bei unsicheren Veröffentlichungen (machen Sie Ihre Felder selbstverständlich endgültig). Ich denke, die Leistung könnte verbessert werden, indem ein Teilstring vor dem + erstellt wird, der (seltsamerweise) durch concat ersetzt werden sollte.
Es füllt Ihren String XXX mit bis zu 9 Zeichen mit einem Leerzeichen. Danach werden alle Leerzeichen durch eine 0 ersetzt. Sie können das Leerzeichen und die 0 nach Belieben ändern ...
Sie sollten die staticMethode aufrufen , String.format(…)anstatt eine leere Zeichenfolge zu missbrauchen. Das Speichern von vier Zeichen im Quellcode ist den Verlust der Lesbarkeit sicherlich nicht wert.
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"";}
Lassen Sie mich eine Antwort für einige Fälle hinterlassen, in denen Sie links / rechts (oder Präfix / Suffix-Zeichenfolge oder Leerzeichen) auffüllen müssen, bevor Sie mit einer anderen Zeichenfolge verketten und die Länge oder eine if-Bedingung nicht testen möchten.
Das gleiche wie bei der ausgewählten Antwort würde ich die StringUtilsvon Apache Commons bevorzugen, aber auf folgende Weise:
Die Antworten von @ck und @Marlon Tarak sind die einzigen, die a verwenden. Dieschar[] ist der beste Ansatz für Anwendungen, bei denen mehrere Auffüllmethoden pro Sekunde aufgerufen werden . Sie nutzen jedoch keine Optimierungen der Array-Manipulation und werden für meinen Geschmack ein wenig überschrieben. Dies kann ohne Schleifen erfolgen .
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));}
Ausgänge:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Sie können getCharsden StringInhalt direkt in das outArray kopieren lassen , anstatt ihn aufzurufen source.toCharArray(), gefolgt von System.arraycopy. Ich würde sogar in Betracht ziehen, die Implementierung zu vereinfachen 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);. Dies scheint fillzwar mehr Arbeit zu leisten, ermöglicht es der JVM jedoch, die standardmäßige Nullfüllung zu beseitigen.
Holger
1
java.util.Formatterwird links und rechts Polsterung tun. Keine Notwendigkeit für ungerade Abhängigkeiten von Drittanbietern (möchten Sie sie für etwas so Triviales hinzufügen).
[Ich habe die Details ausgelassen und diesen Beitrag zum 'Community-Wiki' gemacht, da ich ihn nicht brauche.]
Ich stimme dir nicht zu. In jedem größeren Java-Projekt werden Sie normalerweise so viele Zeichenfolgen manipulieren, dass sich die verbesserte Lesbarkeit und Vermeidung von Fehlern mit Apache Commons Lang lohnt. Sie alle kennen Code wie someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), der mit StringUtils leicht vermieden werden kann.
Bananeweizen
1
Alle Zeichenfolgenoperationen müssen normalerweise sehr effizient sein - insbesondere, wenn Sie mit großen Datenmengen arbeiten. Ich wollte etwas, das schnell und flexibel ist, ähnlich dem, was Sie im Befehl plsql pad erhalten. Außerdem möchte ich keine große Bibliothek für nur eine kleine Sache einfügen. Mit diesen Überlegungen war keine dieser Lösungen zufriedenstellend. Dies sind die Lösungen, die ich gefunden habe und die die besten Benchmarking-Ergebnisse erzielt haben. Wenn jemand sie verbessern kann, fügen Sie bitte Ihren Kommentar hinzu.
Beachten Sie, dass es mit String.toCharArray () aufgerufen wird und das Ergebnis mit dem neuen String ((char []) - Ergebnis) in String konvertiert werden kann. Der Grund dafür ist, dass Sie, wenn Sie mehrere Operationen anwenden, diese alle auf char [] ausführen und nicht weiter zwischen Formaten konvertieren können - hinter den Kulissen wird String als char [] gespeichert. Wenn diese Operationen in der String-Klasse selbst enthalten wären, wäre sie doppelt so effizient gewesen - Geschwindigkeit und Speicher.
Hier ist eine parallele Version für diejenigen von euch, die sehr lange Saiten haben :-)
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));
Antworten:
Apache
StringUtils
hat mehrere Methoden:leftPad
,rightPad
,center
undrepeat
.Beachten Sie jedoch, dass - wie andere in dieser Antwort erwähnt und demonstriert haben -
String.format()
und dieFormatter
Klassen im JDK bessere Optionen sind. Verwenden Sie sie über den Commons-Code.quelle
Seit Java 1.5
String.format()
kann verwendet werden, um eine bestimmte Zeichenfolge links / rechts aufzufüllen.Und die Ausgabe ist:
quelle
1$
? @leo hat eine sehr ähnliche Antwort gegeben, die nicht verwendet wird1$
und anscheinend den gleichen Effekt hat. Macht es einen Unterschied?Auffüllen auf 10 Zeichen:
Ausgabe:
Zeigen Sie '*' für Zeichen des Passworts an:
Die Ausgabe hat dieselbe Länge wie die Kennwortzeichenfolge:
quelle
.replace(' ', '*')
sollte eher die Wirkung der Polsterung zeigen. Der Ausdruck zum Ausblenden von Passwörtern hat dieses Problem ohnehin nicht ... Eine bessere Antwort zum Anpassen der linken und rechten Füllzeichenfolge mithilfe der nativen Java-Funktion finden Sie in meiner anderen Antwort.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
In Guave ist das einfach:
quelle
Etwas Einfaches:
Der Wert sollte eine Zeichenfolge sein. Konvertieren Sie es in einen String, wenn dies nicht der Fall ist. Wie
"" + 123
oderInteger.toString(123)
Die Teilzeichenfolge beginnt vom Zeichenlängen-Zeichenindex bis zur Endlänge der gepolsterten:
Etwas genauer
Pad rechts:
Pad links:
quelle
Schau es dir an
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Der Algorithmus ist jedoch sehr einfach (Pad bis zur Größe der Zeichen):
quelle
Sehen Sie neben Apache Commons auch,
String.format
welche in der Lage sein sollten, sich um einfaches Auffüllen zu kümmern (z. B. mit Leerzeichen).quelle
quelle
str
, daher ist dies korrekt.(length - str.length())
ist0
? Der Formatierer gibt einFormatFlagsConversionMismatchException
Wann aus,%0s
das die Formatzeichenfolge ist.Ich brauchte eine Weile, um das herauszufinden. Der eigentliche Schlüssel ist das Lesen dieser Formatter-Dokumentation.
quelle
Ich weiß, dass dieser Thread etwas alt ist und die ursprüngliche Frage war für eine einfache Lösung, aber wenn es wirklich schnell sein soll, sollten Sie ein char-Array verwenden.
Die Formatierungslösung ist nicht optimal. Durch einfaches Erstellen der Formatzeichenfolge werden zwei neue Zeichenfolgen erstellt.
Die Lösung von Apache kann verbessert werden, indem der sb mit der Zielgröße initialisiert wird, die unten ersetzt wird
mit
würde verhindern, dass der interne Puffer des jdn wächst.
quelle
StringBuffer
nicht mehrere Threads gleichzeitig auf dasStringBuilder
zugreifen können (was in diesem Fall zutrifft), sollten Sie ein (in JDK1.5 +) verwenden, um den Aufwand für die Synchronisierung zu vermeiden.Hier ist eine andere Möglichkeit, nach rechts zu tippen:
quelle
Seit Java 11 kann String.repeat (int) verwendet werden, um einen bestimmten String links / rechts aufzufüllen.
Ausgabe:
quelle
Sie können den Overhead pro Anruf reduzieren, indem Sie die Auffülldaten beibehalten, anstatt sie jedes Mal neu zu erstellen:
Alternativ können Sie die Ergebnislänge zu einem Parameter für die
pad(...)
Methode machen. Nehmen Sie in diesem Fall die Anpassung der ausgeblendeten Auffüllung in dieser Methode anstelle im Konstruktor vor.(Hinweis: Für zusätzliche Gutschrift machen Sie es threadsicher! ;-)
quelle
Fand dies auf Dzone
Pad mit Nullen:
quelle
Sie können die integrierten Methoden StringBuilder append () und insert () zum Auffüllen variabler Zeichenfolgenlängen verwenden:
Zum Beispiel:
quelle
Das funktioniert:
Es füllt Ihren String XXX mit bis zu 9 Zeichen mit einem Leerzeichen. Danach werden alle Leerzeichen durch eine 0 ersetzt. Sie können das Leerzeichen und die 0 nach Belieben ändern ...
quelle
static
Methode aufrufen ,String.format(…)
anstatt eine leere Zeichenfolge zu missbrauchen. Das Speichern von vier Zeichen im Quellcode ist den Verlust der Lesbarkeit sicherlich nicht wert.quelle
Lassen Sie mich eine Antwort für einige Fälle hinterlassen, in denen Sie links / rechts (oder Präfix / Suffix-Zeichenfolge oder Leerzeichen) auffüllen müssen, bevor Sie mit einer anderen Zeichenfolge verketten und die Länge oder eine if-Bedingung nicht testen möchten.
Das gleiche wie bei der ausgewählten Antwort würde ich die
StringUtils
von Apache Commons bevorzugen, aber auf folgende Weise:Erklären:
myString
: Die von mir eingegebene Zeichenfolge kann null seinStringUtils.leftPad(myString, 1)
: Wenn string null ist, würde diese Anweisung auch null zurückgebendefaultString
, um eine leere Zeichenfolge anzugeben, um zu verhindern, dass null verkettet wirdquelle
Die Antworten von @ck und @Marlon Tarak sind die einzigen, die a verwenden. Dies
char[]
ist der beste Ansatz für Anwendungen, bei denen mehrere Auffüllmethoden pro Sekunde aufgerufen werden . Sie nutzen jedoch keine Optimierungen der Array-Manipulation und werden für meinen Geschmack ein wenig überschrieben. Dies kann ohne Schleifen erfolgen .Einfache Testmethode:
Ausgänge:
quelle
getChars
denString
Inhalt direkt in dasout
Array kopieren lassen , anstatt ihn aufzurufensource.toCharArray()
, gefolgt vonSystem.arraycopy
. Ich würde sogar in Betracht ziehen, die Implementierung zu vereinfachenchar[] 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);
. Dies scheintfill
zwar mehr Arbeit zu leisten, ermöglicht es der JVM jedoch, die standardmäßige Nullfüllung zu beseitigen.java.util.Formatter
wird links und rechts Polsterung tun. Keine Notwendigkeit für ungerade Abhängigkeiten von Drittanbietern (möchten Sie sie für etwas so Triviales hinzufügen).[Ich habe die Details ausgelassen und diesen Beitrag zum 'Community-Wiki' gemacht, da ich ihn nicht brauche.]
quelle
Alle Zeichenfolgenoperationen müssen normalerweise sehr effizient sein - insbesondere, wenn Sie mit großen Datenmengen arbeiten. Ich wollte etwas, das schnell und flexibel ist, ähnlich dem, was Sie im Befehl plsql pad erhalten. Außerdem möchte ich keine große Bibliothek für nur eine kleine Sache einfügen. Mit diesen Überlegungen war keine dieser Lösungen zufriedenstellend. Dies sind die Lösungen, die ich gefunden habe und die die besten Benchmarking-Ergebnisse erzielt haben. Wenn jemand sie verbessern kann, fügen Sie bitte Ihren Kommentar hinzu.
quelle
Verwenden Sie diese Funktion.
wie benutzt man?
Ausgabe: 01 02 03 04 .. 11 12
quelle
Viele Leute haben einige sehr interessante Techniken, aber ich mag es einfach zu halten, also gehe ich so vor:
quelle
Eine einfache Lösung ohne API lautet wie folgt:
quelle
Java-Oneliner, keine schicke Bibliothek.
Pad Links, nicht einschränken
Pad Richtig, nicht einschränken
Pad Links, Begrenzung auf Padlänge
Pad Rechts auf Limitlänge beschränken
quelle
Wie wäre es mit Rekursion? Die unten angegebene Lösung ist mit allen JDK-Versionen kompatibel und es sind keine externen Bibliotheken erforderlich :)
HINWEIS : Bei dieser Lösung wird das Auffüllen angehängt. Mit einer kleinen Änderung können Sie dem Pad-Wert ein Präfix voranstellen.
quelle
Hier ist eine parallele Version für diejenigen von euch, die sehr lange Saiten haben :-)
quelle
Auffüllbeispiele in Guave:
Auffüllbeispiele in Apache Commons:
Auffüllbeispiele in JDK:
quelle
Eine einfache Lösung wäre:
quelle
Wie ist das
Die Zeichenfolge ist "Hallo" und die erforderliche Auffüllung ist 15 mit der linken Auffüllung "0"
quelle