微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java:循环中的String.replaceAllvs matcher.replaceAll

如何解决Java:循环中的String.replaceAllvs matcher.replaceAll

这可能是一个非常简单的问题,也可能是一个重复的问题(尽管我确实事先进行了检查),但是在String.replaceAll()matcher.replaceAll()循环中使用时,它便宜吗?
有人告诉我

Pattern regexPattern = Pattern.compile("[^a-zA-Z0-9]");
Matcher matcher;
String thisWord;
while (Scanner.hasNext()) {
   matcher = regexPattern.matcher(Scanner.next());
   thisWord = matcher.replaceAll("");
   ...
} 

更好,因为您只需要编译一次正则表达式,我认为

的好处
String thisWord;
while (Scanner.hasNext()) {
   thisWord = Scanner.next().replaceAll("[^a-zA-Z0-9]","");
   ...
}

远远超过了matcher方法,因为不必每次都初始化matcher。 (我知道matcher已经存在,因此您无需重新创建它。)

有人可以解释我的推理是错误的吗?我误解了Pattern.matcher()的作用吗?

解决方法

在OpenJDK中,String.replaceAll的定义如下:

    public String replaceAll(String regex,String replacement) {
        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
    }

[code link]

因此,至少在该实现中,它不会比仅编译一次模式并使用Matcher.replaceAll提供更好的性能。

可能还有其他JDK实现,其中String.replaceAll的实现方式有所不同,但是如果它在任何方面都比Matcher.replaceAll更好,我会感到非常惊讶。


[…],因为不必每次都初始化匹配器。 (我知道匹配器已经存在,因此您无需重新创建它。)

我认为您在这里有误会。您确实确实在每次循环迭代时都创建了一个新的Matcher实例;但这很便宜,无需考虑性能。


顺便说一句,如果您不需要变量,实际上并不需要一个单独的“ matcher”变量。编写以下内容,您将获得完全相同的行为和性能:

   thisWord = regexPattern.matcher(Scanner.next()).replaceAll("");
,

如果重置相同的匹配器,则有一种更有效的方法,这样就不会在循环内的每种情况下都重新生成该匹配器,它会复制与Pattern结构有关的大多数相同信息。

Pattern regexPattern = Pattern.compile("[^a-zA-Z0-9]");
Matcher matcher = regexPattern.matcher("");
String thisWord;
while (Scanner.hasNext()) {
   matcher = matcher.reset(Scanner.next());
   thisWord = matcher.replaceAll("");
   // ...
} 

在循环regexPattern.matcher("")之外创建匹配器会产生一次性费用,但是对matcher.reset(xxx)的调用会更快,因为它们会重用该匹配器,而不是重新生成新的匹配器实例每一次。这样可以减少所需的GC数量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。