我知道的一种方法是对子字符串应用Matcher,另一种方法是手动搜索第一个不是小写的字符。
那么,有什么好方法可以做到这一点呢?
对于这样一个简单的任务,使用Matcher似乎是一种巨大的夸大。
实际上,可以使用与C++ find_first_not_of()等效的方法,但是Java库中似乎没有这样的方法。
更新:
嗯,Matcher的方式比手工慢4-10倍,但是,如果做得正确的话,是很好的和可读性的(参见Andreas的答案)。
然而,由于习惯了代码通常应该尽可能高效(保持代码的可读性)的想法,我仍然有兴趣看看是否有可能使用标准库和/或原生Java技巧更快地完成相同的事情。
更新2:
我发现了一种更快的惯用方法:流API
因此,目前发现的方法是:
// 1. Andreas' correction of the Matcher way
static String getLowercaseSubstringAt (final String s, final int pos) {
Matcher m = Pattern.compile("^\\p{Ll}+").matcher(s).region(pos, s.length());
return (m.find() ? m.group() : "");
}
// 2. The same with a static Pattern: 2.5 times faster
// I thought the compiler would optimize it by default
// Don't like the idea to make the Pattern external
static Pattern p = Pattern.compile("^\\p{Ll}+");
static String getLowercaseSubstringAt (final String s, final int pos) {
Matcher m = p.matcher(s).region(pos, s.length());
return (m.find() ? m.group() : "");
}
// 3. Stream API with a range of indices: 3x the speed of the first
// Makes use of the Java way to say `find_first(_not)_of()`
static String getLowercaseSubstringAt (final String s, final int pos) {
int idx = IntStream.range(pos, s.length())
.filter(i -> !Character.isLowerCase(s.charAt(i)))
.findFirst()
.orElse(s.length());
return s.substring(pos, idx);
}
// 4. Doing it manually. Relatively dirty, but fast. 10x the speed
static String getLowercaseSubstringAt (final String s, final int pos) {
for (int i = pos; i < s.length(); i++)
if (!Character.isLowerCase(s.charAt(i)))
return s.substring(pos, i);
return s.substring(pos);
}就语言而言,Stream API看起来是最好的选择:不需要外部资源,干净,相对较快。
发布于 2017-04-29 22:56:54
我不知道为什么你说Matcher方式在代码和时间上都是非常浪费的。
当然,正则表达式比简单的for循环慢,但除非您在一个紧密的循环中重复执行此操作(1000+时间),否则您不会注意到其中的差异。在您测量性能并发现问题之前,它可能不是问题。提防过早的优化。
但是在代码上很浪费?只是因为你做错了:
static String getLowercaseSubstringAt (final String s, final int pos) {
Matcher m = Pattern.compile("^\\p{Ll}+").matcher(s).region(pos, s.length());
return (m.find() ? m.group() : "");
}由于您的非正则表达式使用的是Character.isLowerCase()的全小写检查,因此我也更新了正则表达式来实现这一点。
https://stackoverflow.com/questions/43694875
复制相似问题