首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从给定位置提取小写子字符串的好方法是什么?

从给定位置提取小写子字符串的好方法是什么?
EN

Stack Overflow用户
提问于 2017-04-29 19:06:59
回答 1查看 96关注 0票数 1

我知道的一种方法是对子字符串应用Matcher,另一种方法是手动搜索第一个不是小写的字符。

那么,有什么好方法可以做到这一点呢?

对于这样一个简单的任务,使用Matcher似乎是一种巨大的夸大。

实际上,可以使用与C++ find_first_not_of()等效的方法,但是Java库中似乎没有这样的方法。

更新:

嗯,Matcher的方式比手工慢4-10倍,但是,如果做得正确的话,是很好的和可读性的(参见Andreas的答案)。

然而,由于习惯了代码通常应该尽可能高效(保持代码的可读性)的想法,我仍然有兴趣看看是否有可能使用标准库和/或原生Java技巧更快地完成相同的事情。

更新2:

我发现了一种更快的惯用方法:流API

因此,目前发现的方法是:

代码语言:javascript
复制
// 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看起来是最好的选择:不需要外部资源,干净,相对较快。

EN

回答 1

Stack Overflow用户

发布于 2017-04-29 22:56:54

我不知道为什么你说Matcher方式在代码和时间上都是非常浪费的。

当然,正则表达式比简单的for循环慢,但除非您在一个紧密的循环中重复执行此操作(1000+时间),否则您不会注意到其中的差异。在您测量性能并发现问题之前,它可能不是问题。提防过早的优化。

但是在代码上很浪费?只是因为你做错了:

代码语言:javascript
复制
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()的全小写检查,因此我也更新了正则表达式来实现这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43694875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档