设置 StringBuilder 对象的最佳方法是什么?

What's the best way to set a StringBuilder object?

我创建了一个没有任何值的 StringBuilder 对象,然后附加了一些值。后来我想用完全不同的字符串替换该对象。

代码如下:

StringBuilder finalVersion = new StringBuilder();
finalVersion.append("6.0")
for (int i = 0; i < list.length(); i++) {
    if(/*...*/){
       finalVersion.append(".2");
    } else {
       finalVersion.append(".1");
    }
    if (/*...*/) {
        if (/*...*/) {
            finalVersion = new StringBuilder("Invalid parameter"));
         }
    }
}

我所做的是创建一个新对象来更改值,但也许有更好的方法而不使用 stringBuilder.setLength(0);

有人可以帮忙吗?

您可以使用 replace。此方法不会创建新的 StringBuilder 对象。

builder.replace(0, b.length(), "Invalid parameter");

或者,如果您可以在两个语句中执行此操作,则可以 setLength(0),然后 append

但实际上,您不必担心创建新的 StringBuilder 除非您确实遇到性能问题。

To solve it I created a new object to change the value but I guess there is a better approach without use sb.setLength(0)

这两个都是很好的方法。另一个是 sb.delete(0, sb.length()).

而当你想替换现有的字符串内容时,sb.replace(0, sb.length(), "new content")是另一种选择。

这真的取决于你的目标是什么:

  • 调用 new StringBuffer(...) 将为您提供一个新分配的对象,该对象具有默认容量或您指定的容量。

  • setLengthdeletereplace 方法将回收现有对象。这有优点也有缺点。

    • 从好的方面来说,您不会分配新对象1 ... 所以垃圾更少。

    • 在减号方面,字符串缓冲区使用与以前相同数量的 space,无论是否 需要 。此外,如果您重复执行此操作,缓冲区及其后备数组很可能会被 GC 占用,从而增加长期内存负载。您可以通过调用 sb.trimToSize() 来释放未使用的容量,但这很容易导致重新分配;即你试图通过不使用 new.

    • 来避免什么

我的建议是使用 new 除非 上下文意味着你 不能,或者您的分析告诉您 new 产生了太多垃圾。

查看代码2,我认为 setLength 清空 StringBuffer 应该比 delete 快一点。当您用新内容替换内容时,它会变得更加复杂。现在你比较

   sb.setLength(); sb.append("new content");

对比

   sb.replace(0, sb.length(), "new content");

需要对其进行测量...如果您足够关心3 比较案例的性能。


1 - 除非替换字符串足够大,缓冲区需要增长才能容纳它。

2 - 通过我阅读各种版本的 StringBuilderAbstractStringBuilder 代码,delete 方法将始终调用 System.arraycopy。但是,要了解性能影响,需要针对不同大小的 StringBuilder 和不同的 Java 版本仔细进行基准测试。

3 - 实际上,如果您需要关心。当心过早优化的弊端。