将 stringbuilder 与 for 循环一起使用

0 java stringbuilder for-loop

 private String generateSuffix(List<String[]> searches, List<String[]> sorts) {
        String ret = "";
        if (searches != null && !searches.isEmpty()) {
            ret += "where ";
            for (String[] search : searches) {
                if (search.length < 3) {
                    continue;
                }
                ret += search[0] + search[1] + search[2] + " and ";
            }
            ret = ret.substring(0, ret.length() - 5);
        }

        ret += " order by ";
        if (sorts != null && !sorts.isEmpty()) {
            for (String[] sort : sorts) {
                if (sort.length < 2) {
                    continue;
                }
                ret += sort[0] + " " + sort[1] + ",";
            }
        }
        return ret;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的 SONAR 扫描表明使用“+”在循环中连接字符串是一个主要错误。它没有提供太多关于如何修复此错误的见解。这种情况下可以使用StringBuilder吗?如果是这样,我将如何使用增强的 for 循环来实现 StringBuilder?我对 StringBuilder 的使用不太熟悉。

另外,我可以在列表中添加 StringBuilder 吗,如下所示?我需要删除代码“value += ds;” 值 = d + "" "。

private List<TransactionSearchField> checkSearches(List<TransactionSearchField> searchesIn) {
    List<TransactionSearchField> searches = new ArrayList<TransactionSearchField>();
    if (searchesIn != null) {
        for (TransactionSearchField search : searchesIn) {
            String value = search.getValue();
            if (value != null && value.length() > 0) {
                if (search.getDataType().equals(double.class)) {
                    String[] dSplit = value.split(",");
                    value = "";
                    for (String ds : dSplit) {
                        value += ds;
                    }
                    double d;
                    try {
                        d = Double.parseDouble(value);
                        value = d + "";
                    } catch (IllegalArgumentException e) {
                        value = "";
                    }
                } else if (search.getDataType().equals(Date.class)) {
                    value = formatDate(generateDate(value));
                }
                searches.add(new TransactionSearchField(search.getDataType(), search.getTableField(), search.getLogic(), value, search.getViewField()));
            }
        }
    }
    return searches;
}
Run Code Online (Sandbox Code Playgroud)

Psh*_*emo 5

代码如下

result = result + newPart;
Run Code Online (Sandbox Code Playgroud)

本质上是(假设结果是字符串)

result = new StringBuilder(result).append(newPart).toString();
Run Code Online (Sandbox Code Playgroud)

如果将其放入循环中,则在每次迭代中,您将创建对象,该对象将从字符串new StringBuilder中复制所有字符,然后追加到它,然后创建另一个将存储在变量中的字符串。resultnewPartresult

在长字符串的情况下,这是非常低效的,因为即使要添加一小部分,我们也需要复制当前结果中的所有字符(两次,一次在创建 StringBuilder 时,一次在创建新结果 String 时)。

为了避免这个问题,而不是像这样的字符串连接

String result = "";
for (String newPart : otherStrings){
    result = result + newPart;
    result = result + ", ";
}
Run Code Online (Sandbox Code Playgroud)

我们应该创建一个 StringBuilder 和appendid 的新部分。StringBuilder 类的优点是它在字符数组中保存字符,该数组相当大,因此它有可用空间用于新字符。如果该空间在某些时候不够,StringBuilder 将创建两倍大小的新数组并复制其中的所有字符。因此它限制了我们需要调整数组大小和迭代所有字符的次数。

所以正确的解决方案如下所示:

StringBuilder sb = new StringBuilder();
for (String newPart : otherStrings){
    sb.append(newPart);
    sb.append(", ");
    //you could also chain these methods
    //sb.append(newPart).append(", ");
}
String result = sb.toString();
Run Code Online (Sandbox Code Playgroud)

顺便说一句,StringBuilder允许对保留的字符进行操作。例如,我们可以通过删除其中的一些字符StringBuilder.delete(int start, int end)