462

Is there some easy way to pad Strings in Java?

Seems like something that should be in some StringUtil-like API, but I can't find anything that does this.

Jason Plank
  • 2,322
  • 4
  • 29
  • 39
pvgoddijn
  • 11,653
  • 14
  • 43
  • 54

30 Answers30

669

Since Java 1.5, String.format() can be used to left/right pad a given string.

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) + "*");
}

And the output is:

Howto               *
               Howto*
RealHowTo
  • 32,895
  • 11
  • 68
  • 83
  • 39
    What if you need to lpad with other chars (not spaces) ? Is it still possible with String.format ? I am not able to make it work... – Guido Aug 11 '09 at 15:48
  • 6
    AFAIK String.format() can't do that but it's not too difficult to code it, see http://www.rgagnon.com/javadetails/java-0448.html (2nd example) – RealHowTo Dec 07 '09 at 14:47
  • 61
    @Nullw0rm, if you're referring to rgagnon.com, be aware that RealHowTo is the author of rgagnon.com too, so he would be crediting himself... – Colin Pickard Nov 12 '10 at 14:17
  • 3
    at least on my JVM, the "#" doesn't work, the "-" is fine. (Just delete the #). This may be consistent with the formatter documentation, I dunno; it says "'#' '\u0023' Requires the output use an alternate form. The definition of the form is specified by the conversion." – gatoatigrado Jan 02 '11 at 21:25
  • 1
    WIth jre6, "%1$#" is ok but with jre7 "%1$#" throws java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = #. I have updated this answer by removing the "#". – RealHowTo Aug 02 '12 at 13:52
  • 6
    Thanks for the awesome answer. I have a doubt though, what is the `1$` for? @leo has made a very similar answer that doesn't use `1$` and it apparently has the same effect. Does it make a difference? – Fabrício Matté Mar 08 '13 at 19:14
  • 1
    Oh of course it is to explicitly force argument order of String.format, sorry for the stupid question. `:P` Even then, it serves virtually no use in this case, I assume. – Fabrício Matté Mar 08 '13 at 19:24
  • 1
    Note that `n` _must_ be greater than `0`. – Ben Leggiero Sep 21 '15 at 17:32
  • Since Java 11, use String.repeat, see below the answer by Eko Setiawan. – Jonathan Rosenne Jul 17 '20 at 20:49
  • I am getting a lot of weird results... pass on this solution – john ktejik Aug 25 '20 at 19:35
269

Padding to 10 characters:

String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');

output:

  *******foo
  bar*******
  longer*than*10*chars

Display '*' for characters of password:

String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');

output has the same length as the password string:

  secret123
  *********
leo
  • 3,204
  • 3
  • 18
  • 17
  • 52
    Just as long as we all remember not to pass in a string with spaces... :D – leviathanbadger Jan 18 '13 at 03:20
  • 5
    I'm with @aboveyou00--this is a horrendous solution for strings with spaces, including the example provided by leo. A solution for padding a string on the left or the right should not alter the input string as it appears in the output, unless the input string's original padding causes it to exceed the specified padding length. – Brian Warshaw Jan 29 '15 at 16:24
  • 3
    Acknowledge the space issue. `.replace(' ', '*')` was rather intended to show the effect of padding. The password hiding expression does not have this issue anyway... For a better answer on customizing the left and right padding string using native Java feature see my other answer. – leo Aug 31 '17 at 21:12
  • If the string contains only single spaces and you want to pad with different characters, you can use regex replace with look behind/ahead: `String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")` or `String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")` – Jaroslaw Pawlak Jun 26 '18 at 11:01
197

Apache StringUtils has several methods: leftPad, rightPad, center and repeat.

But please note that — as others have mentioned and demonstrated in this answerString.format() and the Formatter classes in the JDK are better options. Use them over the commons code.

Neuron
  • 3,776
  • 3
  • 24
  • 44
GaryF
  • 22,828
  • 9
  • 56
  • 72
  • 93
    java.util.Formatter (and String.format()) does this. Always prefer the JDK to an external library if the JDK version does the job (which it does). – cletus Dec 23 '08 at 12:02
  • 6
    For several reasons, I'd now prefer Guava to Apache Commons; [this answer shows how to do it in Guava](http://stackoverflow.com/a/7502863/56285). – Jonik Oct 24 '12 at 12:37
  • 1
    @Jonik would you care to list some of your reasons? The APIs look pretty much the same. – glen3b May 18 '14 at 05:18
  • 3
    @glen3b: For an individual utility, like these string padding helpers, it really makes no difference which lib to use. That said, Guava is overall a more modern, cleaner and better documented lib than its counterparts in various Apache Commons projects (Commons Lang, Commons Collections, Commons IO, etc). It's also built by really smart guys (Kevin Bourrillion et al), many of whom are [active at SO](http://stackoverflow.com/tags/guava/topusers). Myself I ended up replacing the various Apache Commons libs with just Guava years ago, and have had no regrets. – Jonik May 18 '14 at 18:59
  • 3
    @glen3b: Some good [further reading at this question](http://stackoverflow.com/questions/4542550/what-are-the-big-improvements-between-guava-and-apache-equivalent-libraries). – Jonik May 18 '14 at 19:00
  • 2
    `StringUtils`/`Strings` is still the better choice IMO when the size of the pad is a runtime variable. – OrangeDog Jun 08 '16 at 12:56
87

In Guava, this is easy:

Strings.padStart("string", 10, ' ');
Strings.padEnd("string", 10, ' ');
Garrett Hall
  • 27,772
  • 10
  • 56
  • 73
  • Adding 2.7MB code dependency for just a padding that's already included in the standard JDK? Seriously. – foo May 14 '21 at 19:30
36

Something simple:

The value should be a string. convert it to string, if it's not. Like "" + 123 or Integer.toString(123)

// let's assume value holds the String we want to pad
String value = "123";

Substring start from the value length char index until end length of padded:

String padded="00000000".substring(value.length()) + value;

// now padded is "00000123"

More precise

pad right:

String padded = value + ("ABCDEFGH".substring(value.length())); 

// now padded is "123DEFGH"

pad left:

String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;

// now padded is "ABCDE123"
m02ph3u5
  • 2,735
  • 6
  • 34
  • 45
Shimon Doodkin
  • 3,676
  • 29
  • 33
26

Have a look at org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar).

But the algorithm is very simple (pad right up to size chars):

public String pad(String str, int size, char padChar)
{
  StringBuilder padded = new StringBuilder(str);
  while (padded.length() < size)
  {
    padded.append(padChar);
  }
  return padded.toString();
}
Arne Burmeister
  • 18,467
  • 8
  • 50
  • 89
22

Besides Apache Commons, also see String.format which should be able to take care of simple padding (e.g. with spaces).

Miserable Variable
  • 27,314
  • 13
  • 69
  • 124
16
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...
Eduardo
  • 177
  • 1
  • 2
12

Since Java 11, String.repeat(int) can be used to left/right pad a given string.

System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));

Output:

*****apple
apple*****
Eko Setiawan
  • 140
  • 1
  • 7
7

This took me a little while to figure out. The real key is to read that Formatter documentation.

// 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);
Nthalk
  • 3,606
  • 1
  • 23
  • 19
  • Why make the end so complicated? You could have just done String hex = String.format("%032x", digest); and had the exact same results, just without a needless replace() and having to use the $ to access specific variables (there's only one, after all.) – ArtOfWarfare Oct 17 '12 at 17:37
  • @ArtOfWarfare fair point. Someone originally asked for padding hex values in another question, I saw that I had a link to the formatter documentation. It's complicated for completeness. – Nthalk Mar 04 '14 at 21:42
6

i know this thread is kind of old and the original question was for an easy solution but if it's supposed to be really fast, you should use a char array.

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;
}

the formatter solution is not optimal. just building the format string creates 2 new strings.

apache's solution can be improved by initializing the sb with the target size so replacing below

StringBuffer padded = new StringBuffer(str); 

with

StringBuffer padded = new StringBuffer(pad); 
padded.append(value);

would prevent the sb's internal buffer from growing.

ck.
  • 61
  • 1
  • 2
  • If the `StringBuffer` can't be accessed by multiple threads at once (which in this case is true), you should use a `StringBuilder` (in JDK1.5+) to avoid the overhead of synchronization. – glen3b May 20 '14 at 23:40
5

Here is another way to pad to the right:

// 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-------";
Jason Plank
  • 2,322
  • 4
  • 29
  • 39
fawsha1
  • 759
  • 8
  • 11
4

You can reduce the per-call overhead by retaining the padding data, rather than rebuilding it every time:

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);
    }

}

As an alternative, you can make the result length a parameter to the pad(...) method. In that case do the adjustment of the hidden padding in that method instead of in the constructor.

(Hint: For extra credit, make it thread-safe! ;-)

joel.neely
  • 29,629
  • 9
  • 52
  • 63
  • 1
    That is thread safe, except for unsafe publication (make your fields final, as a matter of course). I think performance could be improved by doing a substring before the + which should be replaced by concat (strangely enough). – Tom Hawtin - tackline Dec 24 '08 at 12:44
4

Found this on Dzone

Pad with zeros:

String.format("|%020d|", 93); // prints: |00000000000000000093|
OJVM
  • 1,131
  • 1
  • 21
  • 35
  • This should be the answer, simple and concise, no need to install external libraries. – Wong Jia Hau Aug 27 '18 at 04:10
  • Works with numeric values, but not for String values: ie, for "A83" it will not work. The 0 after the percent will rase an exception. – TwiXter Feb 11 '21 at 17:29
2

you can use the built in StringBuilder append() and insert() methods, for padding of variable string lengths:

AbstractStringBuilder append(CharSequence s, int start, int end) ;

For Example:

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());
ef_oren
  • 21
  • 2
2

Let's me leave an answer for some cases that you need to give left/right padding (or prefix/suffix string or spaces) before you concatenate to another string and you don't want to test length or any if condition.

The same to the selected answer, I would prefer the StringUtils of Apache Commons but using this way:

StringUtils.defaultString(StringUtils.leftPad(myString, 1))

Explain:

  • myString: the string I input, can be null
  • StringUtils.leftPad(myString, 1): if string is null, this statement would return null too
  • then use defaultString to give empty string to prevent concatenate null
bluish
  • 23,093
  • 23
  • 110
  • 171
Osify
  • 2,004
  • 22
  • 40
2

@ck's and @Marlon Tarak's answers are the only ones to use a char[], which for applications that have several calls to padding methods per second is the best approach. However, they don't take advantage of any array manipulation optimizations and are a little overwritten for my taste; this can be done with no loops at all.

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);
}

Simple test method:

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));
}

Outputs:

012345678901234567890123456789
cats                          
                          cats
                cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too long for your own good, buddy 
ndm13
  • 1,087
  • 14
  • 19
  • 1
    You can use [`getChars`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#getChars-int-int-char:A-int-) to let the `String` copy its contents directly into the `out` array, instead of calling `source.toCharArray()`, followed by `System.arraycopy`. I’d even consider simplifying the implementation to `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);`; while this looks like `fill` would do more work, it actually allows the JVM to eliminate the default zero-filling. – Holger Apr 01 '19 at 14:39
2

This works:

"".format("%1$-" + 9 + "s", "XXX").replaceAll(" ", "0")

It will fill your String XXX up to 9 Chars with a whitespace. After that all Whitespaces will be replaced with a 0. You can change the whitespace and the 0 to whatever you want...

Sebastian S.
  • 443
  • 1
  • 4
  • 16
  • You should invoke the `static` method as `String.format(…)` instead of abusing an empty string. Saving four characters in source code surely isn’t worth the loss of readability. – Holger Apr 01 '19 at 14:17
2
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 "";
}
1

A lot of people have some very interesting techniques but I like to keep it simple so I go with this :

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();
}
Aelphaeis
  • 2,495
  • 3
  • 21
  • 41
  • 2
    This is very inefficient, you should use a StringBuilder – wkarl Feb 25 '16 at 10:23
  • Since you already know the length, you should tell the StringBuilder to allocate that much space when you instantiate it. – Ariel Jun 15 '18 at 00:28
  • @Ariel interesting that you mention that because I was just talking to someone else about that today lol. – Aelphaeis Jun 15 '18 at 19:05
1

java.util.Formatter will do left and right padding. No need for odd third party dependencies (would you want to add them for something so trivial).

[I've left out the details and made this post 'community wiki' as it is not something I have a need for.]

Tom Hawtin - tackline
  • 139,906
  • 30
  • 206
  • 293
  • 4
    I disagree. In any larger Java project you will typically do such a lot of String manipulation, that the increased readability and avoidance of errors is well worth using Apache Commons Lang. You all know code like someString.subString(someString.indexOf(startCharacter), someString.lastIndexOf(endCharacter)), which can easily be avoided with StringUtils. – Bananeweizen May 30 '11 at 20:15
1

All string operation usually needs to be very efficient - especially if you are working with big sets of data. I wanted something that's fast and flexible, similar to what you will get in plsql pad command. Also, I don't want to include a huge lib for just one small thing. With these considerations none of these solutions were satisfactory. This is the solutions I came up with, that had the best bench-marking results, if anybody can improve on it, please add your comment.

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;
    }
}
  • note it is called with String.toCharArray() and the result can be converted to String with new String((char[])result). The reason for this is, if you applying multiple operations you can do them all on char[] and not keep on converting between formats - behind the scenes, String is stored as char[]. If these operations were included in the String class itself, it would have been twice as efficient - speed and memory wise.
EarlB
  • 71
  • 7
1

Use this function.

private String leftPadding(String word, int length, char ch) {
   return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}

how to use?

leftPadding(month, 2, '0');

output: 01 02 03 04 .. 11 12

Samet ÖZTOPRAK
  • 2,428
  • 3
  • 23
  • 26
1

This utility class that is useful for left pad and zero fill of Strings. I hope that it helps someone!

package your.package.name;

/**
 * Utility class for left pad and zero fill of Strings.
 * 
 */
public class LeftPad {

    public static String lpad(String string, int length, char fill) {
        return new String(lpad(string.toCharArray(), length, fill));
    }

    public static String zerofill(String string, int length) {
        return new String(zerofill(string.toCharArray(), length));
    }

    private static char[] lpad(char[] chars, int length, char fill) {

        int delta = 0;
        int limit = 0;

        if (length > chars.length) {
            delta = length - chars.length;
            limit = length;
        } else {
            delta = 0;
            limit = chars.length;
        }

        char[] output = new char[chars.length + delta];
        for (int i = 0; i < limit; i++) {
            if (i < delta) {
                output[i] = fill;
            } else {
                output[i] = chars[i - delta];
            }
        }
        return output;
    }

    private static char[] zerofill(char[] chars, int length) {
        return lpad(chars, length, '0');
    }

    /**
     * For tests!
     */
    public static void main(String[] args) {

        String string = "123";
        char pad = ' ';

        System.out.println("left pad blank: " + string);
        System.out.println("Result: [" + LeftPad.lpad(string, 10, pad) + "]");

        System.out.println();
        System.out.println("zero fill: " + string);
        System.out.println("Result: [" + LeftPad.zerofill(string, 10) + "]");
    }
}

This is the output:

left pad blank: 123
Result: [       123]

zero fill: 123
Result: [0000000123]
fabiolimace
  • 405
  • 3
  • 5
0

A simple solution without any API will be as follows:

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();
}
bluish
  • 23,093
  • 23
  • 110
  • 171
0

Java oneliners, no fancy library.

// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"

Pad Left, don't limit

result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"

Pad Right, don't limit

result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"

Pad Left, limit to pad length

result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"

Pad Right, limit to pad length

result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"
leo
  • 3,204
  • 3
  • 18
  • 17
0

How about using recursion? Solution given below is compatible with all JDK versions and no external libraries required :)

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);
        }
    }

NOTE: This solution will append the padding, with a little tweak you can prefix the pad value.

Saikat
  • 8,190
  • 12
  • 69
  • 94
0

Here's a parallel version for those of you that have very long Strings :-)

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));
David Lilljegren
  • 1,160
  • 12
  • 12
-1

A simple solution would be:

package nl;
public class Padder {
    public static void main(String[] args) {
        String s = "123" ;
        System.out.println("#"+("     " + s).substring(s.length())+"#");
    }
}
-2

How is this

String is "hello" and required padding is 15 with "0" left pad

String ax="Hello";
while(ax.length() < 15) ax="0"+ax;
Satwant
  • 41
  • 2