运行 使用 StringBuilder 的代码上的 pmd 给出有关初始化大小和附加大小的错误

Running pmd on code with StringBuilder gives error about initialized size and appended size

private static String buildSomeString(Map<String, String> data) {
    StringBuilder result = new StringBuilder();
    for (Map.Entry<String, String> field : data.entrySet()) {
       result.append("some literal")
            .append(field.getKey())
            .append("another literal")
            .append(field.getKey())
            .append("and another one")
            .append(field.getValue())
            .append("and the last in this iteration");
     }
     return result.toString();
}

当我 运行 pmd 对此我得到以下错误

StringBuffer constructor is initialized with size 16, but has at least 83 characters appended.

可能是字数不对,因为我发帖前改了文字。

谢谢

当您创建具有默认容量的 StringBuilder 时,如果追加超出该容量,则必须扩展它的内部数组。

如果您知道需要创建的最终字符串的长度,那么您可以创建具有该容量的 StringBuilder,这样它就会知道您需要那么多字符,而它的内部数组不会需要延长。

StringBuilder 的构造函数可以有选择地接收一个 int,它具有要使用的内部缓冲区的大小。如果给定 none(如您的代码中所示),则默认为 16。

当您在 StringBuilder 上追加数据时,它会根据需要自动调整内部缓冲区的大小。这种调整大小意味着创建一个新的、更大的数组,并将旧数据复制到它。这是 "a costly" 操作(注意引号,这是一个微优化,如果您使用的是错误的算法,例如冒泡排序,您会遇到更大的问题)。

对字符串的预期大小进行更有根据的猜测可以避免/最小化此类重新分配。

PMD 不知道地图的内容是什么,但它知道它将至少包含 83 个字符(假定地图不为空)。

这可以通过对大小进行更有根据的猜测来解决,例如:

StringBuilder result = new StringBuilder(83 * data.size()); // 83 or whatever you constant strings account for

如果您可以更好地接近地图键和值的预期值,则可以进一步细化。通常,稍微超过实际预期输出会更好,因为即使这意味着分配更多内存,也有更好的机会完全避免重新分配。