我使用JMH测试了有前途的方法。完整的基准代码。
测试期间的假设(以避免每次都检查极端情况):输入的String长度始终大于1。
结果
BenchmarkMode Cnt Score Error UnitsMyBenchmark.test1 thrpt 20 10463220.493 ± 288805.068 ops/sMyBenchmark.test2 thrpt 20 14730158.709 ± 530444.444 ops/sMyBenchmark.test3 thrpt 20 16079551.751 ± 56884.357 ops/sMyBenchmark.test4 thrpt 20 9762578.446 ± 584316.582 ops/sMyBenchmark.test5 thrpt 20 6093216.066 ± 180062.872 ops/sMyBenchmark.test6 thrpt 20 2104102.578 ± 18705.805 ops/s
分数是每秒的操作数,越高越好。
测验
test1
首先是Andy和Hllink的方法:string = Character.toLowerCase(string.charAt(0)) + string.substring(1);
test2
是第二安迪的方法。Introspector.decapitalize()
丹尼尔(Daniel )也提出了建议,但没有两个if
陈述。if
由于测试假设,第一个被删除。第二个被删除,因为它违反了正确性(即input"HI"
将返回"HI"
)。这几乎是最快的。char c[] = string.toCharArray();
c[0] = Character.toLowerCase(c[0]);
string = new String(c);test3
是对的修改test2
,但不是,而是Character.toLowerCase()
添加了32,当且仅当字符串为ASCII时,该字体才能正常工作。这是最快的。c[0] |= ' '
来自Mike的评论给出了相同的表现。char c[] = string.toCharArray();
c[0] += 32;
string = new String(c);test4
用过的StringBuilder
。StringBuilder sb = new StringBuilder(string);
sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
string = sb.toString();test5
用了两个substring()
电话。string = string.substring(0, 1).toLowerCase() + string.substring(1);
test6
使用反射char value[]
直接在String中进行更改。这是最慢的。try {Field field = String.class.getDeclaredField("value");field.setAccessible(true);char[] value = (char[]) field.get(string);value[0] = Character.toLowerCase(value[0]);} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
结论
如果字符串长度始终大于0,请使用
test2。
如果没有,我们必须检查一些特殊情况:
public static String decapitalize(String string) { if (string == null || string.length() == 0) { return string; } char c[] = string.toCharArray(); c[0] = Character.toLowerCase(c[0]); return new String(c);}如果您确定文本将始终为ASCII并且由于在瓶颈中发现了此代码而正在寻找极佳的性能,请使用
test3。



