使用 replaceAll 和 replaceFirst 方法时如何修复“重构此代码以使用“静态最终”模式”

Raj*_*mar 3 java sonarqube

对于下面的代码,声纳中显示了一个提示:

重构此代码以使用“静态最终”模式。

我不明白,这是什么问题。在声纳中也没有明确解释。

请帮我。

public Boolean validateLabelText(String labelValue, String fieldCell) {
        return labelValue
               .replaceAll(StringUtils.SPACE, StringUtils.EMPTY)
               .equalsIgnoreCase(fieldCell.replaceAll(StringUtils.SPACE, StringUtils.EMPTY)
                                          .replaceFirst(StringUtils.LF, StringUtils.EMPTY));
    }
Run Code Online (Sandbox Code Playgroud)

aga*_*rys 5

重构此代码以使用“静态最终”模式。

您遇到了以下问题:不应不必要地创建正则表达式模式

问题是由这些操作引起的:

.replaceAll(StringUtils.SPACE, StringUtils.EMPTY)
Run Code Online (Sandbox Code Playgroud)
.replaceFirst(StringUtils.LF, StringUtils.EMPTY)
Run Code Online (Sandbox Code Playgroud)

这两种方法都创建了java.util.regex.Pattern类的新实例。这意味着当您的方法执行 100 次时,您的代码将创建 300 个Pattern对象。规则告诉你不应该这样做,因为Pattern是重对象,你可以使用更高效的代码。

如果StringUtils是,org.apache.commons.lang3.StringUtils则解决方案如下。

在第一次操作中

.replaceAll(StringUtils.SPACE, StringUtils.EMPTY)
Run Code Online (Sandbox Code Playgroud)

你想" """(空)替换所有出现的(空格)。此代码应更改为:

.replace(StringUtils.SPACE, StringUtils.EMPTY)
Run Code Online (Sandbox Code Playgroud)

replace方法按原样替换文字。replaceAll将第一个参数视为正则表达式。将空格字符解析为正则表达式是没有意义的,因为输出将完全相同。

下一个

.replaceFirst(StringUtils.LF, StringUtils.EMPTY)
Run Code Online (Sandbox Code Playgroud)

您总是PatternStringUtils.LF. 与其每次都创建一个新模式,您应该编译一次,然后再重用它:

private static final Pattern LF_PATTERN = Pattern.compile(StringUtils.LF, Pattern.LITERAL);
Run Code Online (Sandbox Code Playgroud)
LF_PATTERN.matcher(string).replaceFirst(replacement);
Run Code Online (Sandbox Code Playgroud)

最终的代码应该如下:

private static final Pattern LF_PATTERN = Pattern.compile(StringUtils.LF, Pattern.LITERAL);

public Boolean validateLabelText(String labelValue, String fieldCell) {
    String value1 = labelValue.replace(StringUtils.SPACE, StringUtils.EMPTY);

    String value2 = fieldCell.replace(StringUtils.SPACE, StringUtils.EMPTY);
    value2 = LF_PATTERN.matcher(value2).replaceFirst(StringUtils.EMPTY);

    return value1.equalsIgnoreCase(value2);
}
Run Code Online (Sandbox Code Playgroud)

我不知道你的代码的业务逻辑是什么,所以我将变量命名为value1and value2(我不知道哪个值是current哪个expected)。