字符串生成器与字符串连接

时间:2013-08-26 21:38:28

标签: java stringbuilder string-concatenation

使用字符串生成器而不是纯字符串连接有什么好处和权衡?

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

vs say

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

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

2 个答案:

答案 0 :(得分:51)

在您的特定示例中,没有,因为编译器在内部使用StringBuilder来执行字符串连接。但是,如果连接发生在循环中,则编译器可以创建多个StringBuilderString对象。例如:

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

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

相反,在

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

仅创建了1 StringBuilder和1 String

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

答案 1 :(得分:5)

快速回答是表现: 当您使用本机String类时,它会运行不可变的字符串,这意味着在您编写时

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

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

更快的解决方案是StringBuffer类的设备,它通过智能算法提供缓冲区(显而易见其名称)用于合并字符串,因此在连接过程中不会删除初始字符串。

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