什么时候在Java中使用StringBuilder

在Java中,通常最好使用StringBuilder来进行字符串连接。情况总是这样吗?

我的意思是:创建一个StringBuilder对象,调用append()方法并最终调用toString()的开销是否已经比为两个字符串使用+操作符连接现有字符串的开销更小,还是仅适用于多个(超过两个)字符串?

如果有这样一个阈值,它取决于什么(也许是字符串长度,但以哪种方式)?

最后,你是否愿意牺牲+串接的可读性和简便性来换取StringBuilder在较小情况下的性能,比如两个、三个或四个字符串?

过时的Java优化技巧爪哇都市神话中,显式地使用StringBuilder进行常规连接被认为是过时的。

305591 次浏览

微软认证材料也提出了同样的问题。在. net世界中,StringBuilder对象的开销使得2个String对象的简单连接更加高效。我假设Java字符串也有类似的答案。

看一下:http://www.javaspecialists.eu/archive/Issue068.htmlhttp://www.javaspecialists.eu/archive/Issue105.html

在你的环境中做同样的测试,检查新的JDK或你的Java实现是否用StringStringBuilder更好地执行某种类型的字符串操作。

作为一般规则,总是使用可读性更好的代码,只有在性能有问题时才重构。在这种特定情况下,最新的JDK实际上会在任何情况下将代码优化为StringBuilder版本。

通常只有在循环中进行字符串连接或在编译器无法轻松优化的复杂代码中才需要手动执行。

String连接的问题是它会导致复制带有所有相关代价的String对象。StringBuilder不是线程安全的,因此比StringBuffer更快,而StringBuffer在Java 5之前是首选。根据经验,不应该在循环中进行字符串连接,因为循环将经常被调用。我想在这里或那里做一些连接不会对您造成伤害,只要您不是在谈论数百个,当然这取决于您的性能要求。如果你做的是实时内容,你应该非常小心。

+运算符在内部使用public String concat(String str)。此方法复制两个字符串的字符,因此它的内存需求和运行时复杂度与两个字符串的长度成正比。StringBuilder的工作效率更高。

然而,我读过在这里,使用+操作符的连接代码在后Java 4编译器上被更改为StringBuilder。所以这可能根本不是问题。(虽然我真的会检查这个语句,如果我在我的代码中依赖它!)

如果你在循环中使用字符串连接,就像这样,

String s = "";
for (int i = 0; i < 100; i++) {
s += ", " + i;
}

那么你应该使用StringBuilder(不是StringBuffer)而不是String,因为它更快,占用的内存更少。

如果你有一个陈述,

String s = "1, " + "2, " + "3, " + "4, " ...;

那么你可以使用Strings,因为编译器会自动使用StringBuilder

拉尔夫的回答非常棒。我宁愿使用StringBuilder类来构建/装饰String,因为它的用法更像Builder模式。

public String decorateTheString(String orgStr){
StringBuilder builder = new StringBuilder();
builder.append(orgStr);
builder.deleteCharAt(orgStr.length()-1);
builder.insert(0,builder.hashCode());
return builder.toString();
}

它可以作为一个助手/构建器来构建字符串,而不是字符串本身。

对于两个字符串concat更快,在其他情况下StringBuilder是更好的选择,请参阅我在连接运算符(+)vs concat()中的解释

一些编译器可能不会用StringBuilder等价物替换任何字符串连接。在依赖编译时优化之前,一定要考虑源代码将使用哪些编译器。