什么时候应该显式使用StringBuilder?

时间:2014-07-04 09:50:14

标签: java string concatenation stringbuilder

据我了解,当我String baz = "foo" + "bar" + "123"时,Java编译器在内部用StringBuilder替换表达式。然而,我们的Java老师告诉我们,总是明确地使用StringBuilder ...

是一种好习惯

我是否正确假设我 需要在连接内部循环时显式使用StringBuilder,如an answer to Stack Overflow question String builder vs string concatenation所示?是否还有其他情况需要明确使用StringBuilder代替++=

3 个答案:

答案 0 :(得分:35)

它比“内部循环”更通用 - 它是您想要在多个语句上进行连接的任何时候,并且不需要将中间结果作为字符串。例如:

StringBuilder builder = new StringBuilder("Start");
if (someCondition) {
    builder.append("Foo");
}
if (someOtherCondition) {
    builder.append("Bar");
}
builder.append("End");
String result = builder.toString();

虽然可以将其写为:

String result = "Start" + (someCondition ? "Foo" : "")
    + (someOtherCondition ? "Bar" : "") + "End";

......变得难以阅读。如果if机构内有更多陈述,甚至可能都不可行。

要纠正问题中的某些内容:

  

据我了解,当我执行String baz =“foo”+“bar”+“123”时,java编译器在内部用StringBuilder替换表达式。

不,当您编写该表达式时,编译器会识别出它是编译时常量,并将其替换为

String baz = "foobar123";

这是一个非常好的理由明确使用StringBuilder - 上面的代码在执行时明显比

更有效
String baz = new StringBuilder("foo").append("bar").append("123").toString();

不是编译时常量时,Java编译器将使用StringBuilder执行连接,通常会让您使用比显式更容易理解的代码使用StringBuilder,但没有打击性能。我怀疑你的老师要么没有正确理解字符串连接,要么只是在其他地方读取你应该使用StringBuilder而不完全理解 它是合适的。

答案 1 :(得分:1)

欧比万曾经说过,只有西斯才会以绝对的方式或类似的方式思考......

很高兴您知道Java编译器在内部取代" +"在使用StringBuilder的字符串上。这就是编译器:使生活更轻松。

除非你有循环,如链接的情况,或来自Jon Skeet例子的条件,它主要是可读性和维护的容易性。

更换

return "User " + userName + " said";

new StringBuilder().append("User ").append(userName).append(" said").toString();

使代码更长,可能更难修改,更有可能强制换行,并为您提供更高的性能。

但是,当添加不仅适用于字符串,而且涉及数字时,StringBuilder的解决方案有时可能更具可读性。

return "User" + a + b + " said: " + (c + d);

可能更令人困惑:

return new StringBuilder().append("User ").append(a).append(b)
  .append(" said: ").append(c+d).toString();  

但它主要是意见和编码风格的问题。 "宜"这里不是一个好词。

答案 2 :(得分:1)

它们也适合用C#实现C#的'out'关键字。实施例

public int getInt(StringBuilder error)
{
    int retVal = 0;

    if (someErrorOccured)
        error.append("Couldn't get int because of...");
    else
        retVal = whatItsSupposedToBe;

    return retVal;
}