我的性能增强实现如下.它的速度是基于DecimalFormatter的解决方案的4.5倍:在我的机器上运行,使用带有体面的自制测试工具的Eclipse,结果如下:
>旧方式需要5421毫秒才能拨打600,000个电话(平均每次通话0.009035毫秒)
>新方式需要1219毫秒才能拨打600,000个电话(平均每个电话0.002032毫秒)
一些说明:
>我的解决方案使用固定大小的零块进行填充.如果你预计任何一侧都需要更多填充,那么你必须增加尺寸……显然你可以根据需要动态增加它.
>您上面的评论与代码不太匹配.具体来说,如果返回了一个符号字符,则返回的长度比请求的长一个(您的注释另有说明).我选择相信代码而不是评论.
>我的方法是静态的,因为它不需要实例状态.这是个人品味的东西 – ymmv.
另外:为了模仿原文的行为(但在评论中没有给出),这个:
>如果传入值中的小数位数多于比例值,则抛出ArithmeticException
如果输入值中的整数位数多于(len-scale),则返回的字符串长于len.
如果signed为true,则返回的字符串将比len长
>但是:如果len为负数,则原始字符将返回逗号分隔的字符串.这会抛出IllegalARgumentException
package com.pragmaticsoftwaredevelopment.stackoverflow;
...
final static String formatterZeroes="00000000000000000000000000000000000000000000000000000000000";
protected static String getFormattedDecimal ( String value, int len, int scale, Boolean signed ) throws IllegalArgumentException {
if (value.length() == 0) throw new IllegalArgumentException ("Cannot format a zero-length value");
if (len <= 0) throw new IllegalArgumentException ("Illegal length (" + len + ")");
StringBuffer retVal = new StringBuffer();
String sign=null;
int numStartIdx;
if ("+-".indexOf(value.charAt(0)) < 0) {
numStartIdx=0;
} else {
numStartIdx=1;
if (value.charAt(0) == '-')
sign = "-";
}
if (signed && (value.charAt(0) != '-'))
sign = "+";
if (sign==null)
sign="";
retVal.append(sign);
int dotIdx = value.indexOf('.');
int requestedWholePartLength = (len-scale);
if (dotIdx < 0) {
int wholePartPadLength = (requestedWholePartLength - ((value.length()-numStartIdx)));
if (wholePartPadLength > 0)
retVal.append(formatterZeroes.substring(0, wholePartPadLength));
retVal.append (value.substring(numStartIdx));
if (scale > 0)
retVal.append(formatterZeroes.substring(0, scale));
}
else {
int wholePartPadLength = (requestedWholePartLength - (dotIdx - numStartIdx));
if (wholePartPadLength > 0)
retVal.append(formatterZeroes.substring(0, wholePartPadLength));
retVal.append (value.substring(numStartIdx, dotIdx));
retVal.append (value.substring (dotIdx+1));
int fractionalPartPadLength = (scale - (value.length() - 1 - dotIdx));
if (fractionalPartPadLength > 0)
retVal.append(formatterZeroes.substring(0, fractionalPartPadLength));
}
return retVal.toString();
}