给定下面的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?


当前回答

对于像这样的简单字符串,我更喜欢使用

"string".concat("string").concat("string");

按照顺序,我认为构造字符串的首选方法是使用StringBuilder, string# concat(),然后是重载的+运算符。在处理大字符串时,StringBuilder显著提高了性能,就像使用+操作符会大幅降低性能一样(随着字符串大小的增加,性能会呈指数级下降)。使用.concat()的一个问题是它会抛出nullpointerexception。

其他回答

我可以指出,如果你要迭代一个集合并使用StringBuilder,你可能想要检查Apache Commons Lang和StringUtils.join()(在不同的口味)?

不管性能如何,它可以让你省去无数次创建StringBuilders和for循环的麻烦。

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

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

2个例外:

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

在大多数情况下,你不会看到这两种方法之间的实际区别,但很容易构建一个像下面这样的最坏情况:

public class Main
{
    public static void main(String[] args)
    {
        long now = System.currentTimeMillis();
        slow();
        System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");

        now = System.currentTimeMillis();
        fast();
        System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
    }

    private static void fast()
    {
        StringBuilder s = new StringBuilder();
        for(int i=0;i<100000;i++)
            s.append("*");      
    }

    private static void slow()
    {
        String s = "";
        for(int i=0;i<100000;i++)
            s+="*";
    }
}

输出结果为:

slow elapsed 11741 ms
fast elapsed 7 ms

问题是,+=追加到一个字符串重构一个新的字符串,所以它的代价是字符串长度的线性(两者的和)。

对于你的问题

第二种方法更快,但可读性较差,也更难维护。 正如我所说,在你的具体情况下,你可能看不到区别。

版本1更可取,因为它更短,而且编译器实际上会把它转换成版本2——没有任何性能差异。

更重要的是,我们只有3个 属性,它可能不会生成 不同,但在什么情况下 从concat转到builder?

当你在一个循环中连接时——那通常是编译器不能自己替换StringBuilder的时候。

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

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

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