给定下面的2个toString()实现,哪个是首选的:

public String toString(){
    return "{a:"+ a + ", b:" + b + ", c: " + c +"}";
}

or

public String toString(){
    StringBuilder sb = new StringBuilder(100);
    return sb.append("{a:").append(a)
          .append(", b:").append(b)
          .append(", c:").append(c)
          .append("}")
          .toString();
}

?

更重要的是,鉴于我们只有3个属性,它可能不会有什么不同,但在什么时候你会从+ concat切换到StringBuilder?


当前回答

从Java 1.5开始,使用"+"和StringBuilder.append()的简单一行连接生成完全相同的字节码。

因此,为了代码的可读性,请使用“+”。

2个例外:

多线程环境:StringBuffer 循环中的连接:StringBuilder/StringBuffer

其他回答

对于当前的编译器是否仍然需要使用StringBuilder,似乎存在一些争论。所以我想谈谈我的经验。

我有一个包含10k条记录的JDBC结果集(是的,我需要将它们全部放在一个批处理中)。在我的Java 1.8机器上使用+运算符大约需要5分钟。对于相同的查询,使用stringBuilder.append("")只需不到一秒。

所以差异是巨大的。在循环中,StringBuilder要快得多。

关键在于你是在一个地方写一个连接,还是在一段时间内把它积累起来。

对于您给出的示例,显式使用StringBuilder是没有意义的。(请查看第一个案例的编译代码。)

但是如果你正在构建一个字符串,例如在一个循环中,使用StringBuilder。

为了澄清,假设hugeArray包含数千个字符串,代码如下:

...
String result = "";
for (String s : hugeArray) {
    result = result + s;
}

与以下相比非常浪费时间和内存:

...
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
    sb.append(s);
}
String result = sb.toString();

这是我在Java8中检查的

Using String concatenation Using StringBuilder long time1 = System.currentTimeMillis(); usingStringConcatenation(100000); System.out.println("usingStringConcatenation " + (System.currentTimeMillis() - time1) + " ms"); time1 = System.currentTimeMillis(); usingStringBuilder(100000); System.out.println("usingStringBuilder " + (System.currentTimeMillis() - time1) + " ms"); private static void usingStringBuilder(int n) { StringBuilder str = new StringBuilder(); for(int i=0;i<n;i++) str.append("myBigString"); } private static void usingStringConcatenation(int n) { String str = ""; for(int i=0;i<n;i++) str+="myBigString"; }

如果对大量的字符串使用字符串连接,这真的是一场噩梦。

usingStringConcatenation 29321 ms
usingStringBuilder 2 ms

我认为这张图对于比较所有使用string的类非常有用:

Apache Commons-Lang有一个超级容易使用的ToStringBuilder类。它在处理附加逻辑以及格式化你想要的toString外观方面做得很好。

public void toString() {
     ToStringBuilder tsb =  new ToStringBuilder(this);
     tsb.append("a", a);
     tsb.append("b", b)
     return tsb.toString();
}

将返回类似com.blah的输出。YourClass@abc1321f (a =, = foo)。

或者使用链接的更浓缩的形式:

public void toString() {
     return new ToStringBuilder(this).append("a", a).append("b", b").toString();
}

或者如果你想使用反射来包含类的每个字段:

public String toString() {
    return ToStringBuilder.reflectionToString(this);
}

如果需要,还可以自定义ToString的样式。