Answers:
阿帕奇StringUtils
有几种方法:leftPad
,rightPad
,center
和repeat
。
但请注意-如其他人所说的,并证明了这个答案 - String.format()
和Formatter
JDK中的类是更好的选择。在公共代码上使用它们。
从Java 1.5开始,String.format()
可用于左/右填充给定的字符串。
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) + "*");
}
输出为:
Howto *
Howto*
1$
为了什么?@leo给出了一个非常相似的答案,没有使用1$
,并且显然具有相同的效果。这有什么不同吗?
填充10个字符:
String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');
输出:
*******foo
bar*******
longer*than*10*chars
在密码字符上显示“ *”:
String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');
输出的长度与密码字符串的长度相同:
secret123
*********
.replace(' ', '*')
而是旨在显示填充效果。无论如何,密码隐藏表达式都不存在此问题...有关使用本机Java功能自定义左右填充字符串的更好答案,请参见我的其他答案。
String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
或String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
简单的事情:
该值应该是一个字符串。如果不是,则将其转换为字符串。喜欢"" + 123
或Integer.toString(123)
// let's assume value holds the String we want to pad
String value = "123";
子字符串从值长度char索引开始,直到填充的结束长度:
String padded="00000000".substring(value.length()) + value;
// now padded is "00000123"
更精确
向右垫:
String padded = value + ("ABCDEFGH".substring(value.length()));
// now padded is "123DEFGH"
左垫:
String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;
// now padded is "ABCDE123"
看一看org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
。
但是算法非常简单(按大小字符填充):
public String pad(String str, int size, char padChar)
{
StringBuffer padded = new StringBuffer(str);
while (padded.length() < size)
{
padded.append(padChar);
}
return padded.toString();
}
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
,所以这是正确的。
(length - str.length())
是0
?格式化程序将在格式字符串中抛出一个FormatFlagsConversionMismatchException
when %0s
。
这花了我一段时间才弄清楚。真正的关键是阅读格式化程序文档。
// 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);
我知道这个线程有点陈旧,最初的问题是一个简单的解决方案,但是如果它真的很快,则应该使用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;
}
格式化程序解决方案不是最佳的。仅构建格式字符串会创建2个新字符串。
可以通过将sb初始化为目标大小来改进apache的解决方案,因此请在下面替换
StringBuffer padded = new StringBuffer(str);
与
StringBuffer padded = new StringBuffer(pad);
padded.append(value);
会阻止某人的内部缓冲区增长。
StringBuffer
无法一次被多个线程访问(在这种情况下为true),则应使用StringBuilder
(在JDK1.5 +中)以避免同步的开销。
这是向右滑动的另一种方法:
// 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-------";
从Java 11开始,String.repeat(int)可用于左/右填充给定的字符串。
System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));
输出:
*****apple
apple*****
您可以通过保留填充数据来减少每次呼叫的开销,而不是每次都重新构建它:
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);
}
}
或者,您可以将结果长度作为pad(...)
方法的参数。在这种情况下,请在该方法中而不是在构造函数中调整隐藏的填充。
(提示:要获得额外的信誉,请使其成为线程安全的!;-)
您可以使用内置的StringBuilder append()和insert()方法来填充可变字符串长度:
AbstractStringBuilder append(CharSequence s, int start, int end) ;
例如:
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());
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 "";
}
在某些情况下,让我留下一个答案:在连接到另一个字符串之前,您需要给左/右填充(或前缀/后缀字符串或空格),并且您不想测试长度或任何if条件。
与所选答案相同,我希望使用StringUtils
Apache Commons的,但使用这种方式:
StringUtils.defaultString(StringUtils.leftPad(myString, 1))
说明:
myString
:我输入的字符串,可以为nullStringUtils.leftPad(myString, 1)
:如果string为null,则该语句也将返回nulldefaultString
给出空字符串以防止串联null@ck和@Marlon Tarak的答案是唯一使用a的答案char[]
,对于每秒多次调用填充方法的应用程序来说,这是最好的方法。但是,它们没有利用任何数组操作优化,因此就我的口味而言有些覆盖。这完全可以做到没有循环。
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);
}
简单的测试方法:
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));
}
输出:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too long for your own good, buddy
getChars
让String
复制其内容直接进入out
阵列,而不是调用source.toCharArray()
,其次是System.arraycopy
。我什至考虑简化实现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);
;尽管这看起来fill
会做更多的工作,但实际上它允许JVM消除默认的零填充。
java.util.Formatter
将进行左右填充。不需要奇怪的第三方依赖关系(您是否想为琐碎的事情添加它们)。
[我省略了细节,并把这篇文章设为“社区Wiki”,因为这不是我所需要的。]
通常,所有字符串操作都必须非常高效 -尤其是在处理大量数据时。我想要一种快速灵活的功能,类似于在plsql pad命令中将获得的功能。另外,我不想为一个小东西就包含一个巨大的库。考虑到这些考虑,这些解决方案都不令人满意。这是我想出的解决方案,具有最佳基准测试结果,如果有人可以改进它,请添加您的评论。
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;
}
}
使用此功能。
private String leftPadding(String word, int length, char ch) {
return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}
如何使用?
leftPadding(month, 2, '0');
输出:01 02 03 04 .. 11 12
很多人都有一些非常有趣的技术,但是我想保持简单,所以我继续:
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();
}
没有任何API的简单解决方案如下:
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();
}
Java oneliners,没有精美的库。
// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"
左移垫板,不限
result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"
向右垫,不要限制
result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"
左垫,限制垫长度
result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"
垫右,限制垫长度
result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"
如何使用递归?下面给出的解决方案与所有JDK版本兼容,并且不需要外部库:)
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);
}
}
注意:此解决方案将添加填充,只需稍作调整即可为填充值添加前缀。
番石榴中的填充示例:
Apache Commons中的填充示例:
JDK中的填充示例:
这怎么样
字符串为“ hello”,所需填充为15,左侧填充为“ 0”
String ax="Hello";
while(ax.length() < 15) ax="0"+ax;