The API you expose is very weird. Consider the following call:
padString("foo", true, '\t', 5);
The result being ""
is not really obvious.
Let's just rewrite this from scratch and then compare it to the existing code.
First we're going to have some requirements:
padString
should not make the input smaller.
The code you present correctly deals with that, albeit only comparatively late in the process.
padString
should expose left and right padding
padString
should allow customization of the character used for padding.
With this we can start pulling changes into your code.
The easiest of these to fulfil (incidentally simplifying your code) is the first requirement:
if (input.length() >= maxLength) {
return input;
}
Note how I removed the assignment to output
and instead directly returned the value to simplify the control stucture.
The next requirement is to enable leftPadding and rightPadding. The cleanest way to deal with that is to create separate methods for that, avoiding the boolean leftPad
argument turning the method into a state automaton.
Instead I suggest you expose leftPad
and rightPad
. If you must keep using the API you present here, (which I highly doubt), you can implement padString
as:
return leftPad ? leftPad(input, padChar, maxLength) : rightPad(input, padChar, maxLength);
Now that we have that sorted we want to deal with the actual implementation.
Consider the following simplification:
int padSize = maxLength - input.length();
// generate an "infinite" stream of padChar, limit it to the padSize and collect as String
String padding = Stream.generate(() -> padChar).limit(padSize).collect(Collectors.joining());
StringBuilder builder = new StringBuilder(padding);
if (leftPad) {
// padding is supposed to be on the left, so append the input
builder.append(input);
} else {
// padding is supposed to be on the right, put input before
builder.insert(0, input);
}
assert (builder.length() == maxLength);
return builder.toString();
At this point you should notice something that can be further simplified. The StringBuilder is just a glorified string concatenation:
return leftPad ? padding + input : input + padding;
Note that the padding generation can be slightly simplified using Arrays.fill
:
char[] paddingChars = new char[padSize];
Arrays.fill(paddingChars, padChar);
String padding = new String(paddingChars);
If you want to enforce some more raw performance you could even go so far as to use System.arraycopy
, though I have not done any performance testing.
Note also that I'm reasonably sure this does not correctly handle unicode codepoints outside of the Basic Multilingual Plane (BMP)...
if (input.length() >= maxLength) { return input; }
char[] result = new char[maxLength];
int padSize = maxLength - input.length();
if (leftPad) {
Arrays.fill(result, 0, padSize, padChar);
input.getChars(0, input.length(), result, padSize + 1);
} else {
input.getChars(0, input.length(), result, 0);
Arrays.fill(result, input.length(), maxLength - 1, padChar);
}
return new String(result);
Sidenote: the existing code also does not correctly handle unicode codepoints outside of the BMP. I assume you were not aware of that because most people are not. The gist of it is: Some "characters" require more than 16 bits to be uniquely identifiable. These supplementary characters are ... weird around length and a handful of other String functions.