我必须生成一个包含类的所有数据成员的字符串。例如,如果类定义是
class A
{
private String field1;
private String field2;
private String field3;
...
...
}
然后我想生成一个按顺序包含field1,field2和field3的字符串。但是,我想要做的另一件事是确保以下规则 -
field1 is of length 20. If it is less than 20, pad it with blank spaces.
field2 is of length 10. If it is less than 10, pad it with blank spaces.
field1 is of length 15. If it is less than 15, pad it with blank spaces.
...
...
我打算使用帮助器类来构建这个字符串。我想使用StringBuilder来获取最终的字符串。所以我有类似的东西 -
StringBuilder builder = new StringBuilder();
Helper.addString(field1,20,builder);
现在这个addString函数的实现是我所关注的。对于不同的类,此函数将被调用数千次。所以我想让它尽可能高效。问题是,什么是最有效的方式?目前,我有以下实施 -
public static void addString(String field, int totalLengthOfField, StringBuilder builder)
{
int lengthOfField = field.length();
int numberOfBlankSpacesToPutAfterString = totalLengthOfField - lengthOfField;
if(numberOfBlankSpacesToPutAfterString >=0)
{
builder.append(field);
for(int i=1; i<= numberOfBlankSpacesToPutAfterString; i++)
{
builder.append(" "); // append a blank space
}
}
else
{
// throw exception - field is longer than the maximum allowed length.
}
}
答案 0 :(得分:4)
Java有Formatter
类,它支持使用特定字段的宽度定义创建字符串,非常类似于C中的sprintf()
。String.format()
内部也使用Formatter
对象。 / p>
那就是说Formatter
并不是那么快。您可能最好手动将字符串附加到StringBuilder
并使用具有不同数量空格的小型字符串缓存,以避免始终附加单个空格...
例如,如果你知道填充大小总是小于20个空格,你可以创建一个String[]
表,其中包含0,1,2 ......空格的字符串,并完全跳过循环。如果没有这样的限制,你仍然可以一次追加20个空格的块,直到达到必要的填充大小。
答案 1 :(得分:0)
有什么理由不使用String.format
?
答案 2 :(得分:0)
使用静态方法
String.format("%"+numberOfBlankSpacesToPutAfterString+"s",string)'
答案 3 :(得分:0)
我至少可以看到一个优化。变化:
if(numberOfBlankSpacesToPutAfterString >=0)
要:
if(numberOfBlankSpacesToPutAfterString >0)
如果您要添加0个空格,那么您永远不会进入for循环。这不是什么大不了的事,但听起来有点像。
第二件事:是否需要构建器对象?你可能正在使用
if(numberOfBlankSpacesToPutAfterString >0)
{
for(int i=1; i<= numberOfBlankSpacesToPutAfterString; i++)
{
field +=(" "); // append a blank space
}
}
阅读别人提到的内容,你可以通过增加2的权力间隔来进一步加快速度。
if(numberspaces > 16)
{field +="16spaceshere"
numberspaces -= 16;
}
if(numberspaces > 8)...
if(numberspaces > 4)...
这将使其在场上最多变为4次操作,在numberpacepace上最多变为4次,共计8次。
答案 4 :(得分:0)
考虑检查apache commons(StringUtils)是如何实现的,它们已经遇到了同样的问题,并且已经对方法进行了优化:
public static String rightPad(String str, int size, char padChar) {
if (str == null) {
return null;
}
int pads = size - str.length();
if (pads <= 0) {
return str; // returns original String when possible
}
if (pads > PAD_LIMIT) {
return rightPad(str, size, String.valueOf(padChar));
}
return str.concat(repeat(padChar, pads));
}
public static String repeat(String str, int repeat) {
// Performance tuned for 2.0 (JDK1.4)
if (str == null) {
return null;
}
if (repeat <= 0) {
return EMPTY;
}
int inputLength = str.length();
if (repeat == 1 || inputLength == 0) {
return str;
}
if (inputLength == 1 && repeat <= PAD_LIMIT) {
return repeat(str.charAt(0), repeat);
}
int outputLength = inputLength * repeat;
switch (inputLength) {
case 1 :
return repeat(str.charAt(0), repeat);
case 2 :
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
char[] output2 = new char[outputLength];
for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
output2[i] = ch0;
output2[i + 1] = ch1;
}
return new String(output2);
default :
StringBuilder buf = new StringBuilder(outputLength);
for (int i = 0; i < repeat; i++) {
buf.append(str);
}
return buf.toString();
}
}
答案 5 :(得分:0)
只要你知道你需要的最大填充(20)就很简单了。
private static String spaces = " "; // Whatever you need max!
// your code to compute numberOfBlankSpacesToPutAfterString
if(numberOfBlankSpacesToPutAfterString >= 0) {
builder.append(field);
builder.append(spaces, 0, numberOfBlankSpacesToPutAfterString);
} else {
// Report error
}
答案 6 :(得分:0)
import com.google.common.base.Strings
foo = Strings.repeat(" ", 10)