28

与纯字符串连接相比,使用字符串构建器的好处和权衡是什么?

new StringBuilder(32).append(str1)
                     .append(" test: ")
                     .append(val)
                     .append(" is changed")
                     .toString();

与说

str1 + " test: " + val + " is changed".

str1是一个随机的 10 个字符的字符串。 str2是一个随机的 8 个字符的字符串。

4

2 回答 2

53

In your particular example, none because the compiler internally uses StringBuilders to do String concatenation. If the concatenation occurred in a loop, however, the compiler could create several StringBuilder and String objects. For example:

String s= "" ;
for(int i= 0 ; i < 10 ; i++ )
    s+= "a" ;

每次执行上面的第 3 行时,StringBuilder都会创建一个新对象,并s附加“a”的内容,然后将StringBuilder转换为要分配回的字符串s。共 10 StringBuilders 和 10 Strings。

相反,在

StringBuilder sb= new StringBuilder() ;
for(int i= 0 ; i < 10 ; i++ )
    sb.append( "a" );
String s= sb.toString() ;

仅创建 1StringBuilder和 1 String

主要原因是编译器不够聪明,无法理解第一个循环等同于第二个循环并生成更高效的(字节)代码。在更复杂的情况下,即使是最聪明的编译器也不可能知道。StringBuilder如果你绝对需要这种优化,你必须通过显式使用 s来手动引入它。

于 2013-08-26T21:40:42.970 回答
5

快速的答案是性能:当您使用本机 String 类时,它会操作不可变字符串,这意味着当您编写

  String line = "java";
  String sufix = " is awesome";
  line = line + sufix;

它将创建两个字符串“java”和“is awesome”,而不是从前两个字符串(“java”和“is awesome”)创建一个新的第三个字符串“java is awesome”,稍后可能会被垃圾收集器删除(因为它们不再在应用程序中使用)。这是一个缓慢的解决方案。

更快速的解决方案是 StringBuffer 类的一个设备,它通过智能算法提供一个缓冲区(从它的名字可以明显看出)用于合并字符串,因此在连接过程中不会删除初始字符串。

如果您正在编写单线程应用程序(在多个线程访问同一对象期间没有并发问题),最好应用 StringBuilder ,它比初始 StringBuffer 类具有更快的性能。

于 2013-08-26T21:59:24.070 回答