字符串生成器与字符串串联

与纯字符串串联相比,使用字符串生成器的好处和权衡是什么?

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

vs 说

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

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


答案 1

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

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

每次执行上面的第3行,创建一个新对象,追加“a”的内容,然后将 转换为要赋值回的字符串。总共 10 秒和 10 秒。StringBuildersStringBuildersStringBuilderString

相反,在

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

仅创建 1 和 1。StringBuilderString

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


答案 2

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

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

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

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

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


推荐