在替换之前检查字符串是否包含子字符串是否值得?

Gon*_*lvo 6 java string replace

我今天看到了这段代码

if (translatedText.contains("â")) translatedText = translatedText.replace("â", "a");
if (translatedText.contains("ê")) translatedText = translatedText.replace("ê", "e");
...
Run Code Online (Sandbox Code Playgroud)

这样有22条线,我想知道在替换之前使用"ifs"有什么意义.我理解它的方式是有效的,我们每行读取两次字符串,而直接调用replace方法在没有什么可替换的时候会产生相同的效果,当有什么要替换时它会更快.

但这只是我猜它的工作原理.有人可以确认或纠正我吗?

还有第二个问题.我们正在替换每个元音和每个符号"á","à","â"和"ä".我敢打赌,在Java中有更好的方法.有什么建议?

谢谢.

T.J*_*der 7

文件并没有告诉我们replace,如果没有匹配的字符串,但会做看着Oracle的版本(Java 8)目前的实现:

public String replace(CharSequence target, CharSequence replacement) {
    return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
            this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
Run Code Online (Sandbox Code Playgroud)

...如果你先检查一下,它确实看起来像你避免了一些工作,特别是内存分配(匹配器).

这并不是说可能没有更好的方法来接近这22个替换,可能是通过使用带有字符类的单个正则表达式([âê]等等),编译一次正则表达式,然后使用单个匹配器一个循环,非常大致像这样(灵感来自这个答案):

// You can do this part once somewhere if you want to
Pattern regex = Pattern.compile("[âê]");
// Then:
StringBuffer resultString = new StringBuffer();
Matcher regexMatcher = regex.matcher(translatedText);
while (regexMatcher.find()) {
    String match = regexMatch.group();
    String replacement;
    switch (match) {
        // ...various cases setting `replacement`
    }
    regexMatcher.appendReplacement(resultString, replacement);
}
regexMatcher.appendTail(resultString);
translatedText = resultString.toString();
Run Code Online (Sandbox Code Playgroud)

或者如果你想过早地微观优化它(我的失败):

// You can do this part once somewhere if you want to
Pattern regex = Pattern.compile("[âê]");
// Then:
StringBuffer resultString = null;
Matcher regexMatcher = regex.matcher(translatedText);
while (regexMatcher.find()) {
    if (resultString == null) {
        resultString = new StringBuffer(translatedText.length() + 100);
    }
    String match = regexMatch.group();
    String replacement;
    switch (match) {
        // ...various cases setting `replacement`
    }
    regexMatcher.appendReplacement(resultString, replacement);
}
if (resultString != null) {
    regexMatcher.appendTail(resultString);
    translatedText = resultString.toString();
}
Run Code Online (Sandbox Code Playgroud)

  • 恭喜.500K派对怎么样? (5认同)

Gho*_*ica 3

关于“性能”:这可能实际上取决于 JVM 版本;换句话说:根据replace()更改的实施,如果到位的话可以节省一些正则表达式匹配器成本;或不。

\n\n

关于第二个问题:基本上你那里有很多重复的代码。解决这个问题的一种方法是:

\n\n

您可以定义一些静态最终字段,例如:

\n\n
Map<String, String> replacements = new HashMap<>();\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后填写:

\n\n
replacements.put("\xc3\xa2", "a");\n...\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后用循环替换当前代码,该循环迭代该映射的条目,使用每个键/值作为 Replace() 调用的参数。

\n\n

或者,正如另一个答案所示,你会做类似的事情

\n\n
replacements.put("[\xc3\xa1\xc3\xa0\xc3\xa2\xc3\xa4]", "a");\n
Run Code Online (Sandbox Code Playgroud)\n\n

稍后使用replaceAll()。

\n