字符串生成器与字符串连接
使用字符串生成器而不是纯字符串连接有什么好处和权衡?
new StringBuilder(32).append(str1) .append(" test: ") .append(val) .append(" is changed") .toString();
vs说
str1 + " test: " + val + " is changed".
str1
是一个随机的10个字符串。 str2
是一个随机的8个字符串。
在你的简单例子中,没有,因为编译器使用StringBuilder
来进行字符串连接。 但是,如果连接发生在循环中,则编译器可以创建多个StringBuilder
和String
对象。 例如:
String s= "" ; for(int i= 0 ; i < 10 ; i++ ) s+= "a" ;
执行上面的每个时间行3,创建一个StringBuilder
对象,附加s
的内容,附加“a”,然后将StringBuilder
转换为要分配回s
的String。 共有10个StringBuilder
和10个String
。
相反,在
StringBuilder sb= new StringBuilder() ; for(int i= 0 ; i < 10 ; i++ ) sb.append( "a" ); String s= sb.toString() ;
只创建了1个StringBuilder
和1个String
。
这样做的主要原因是编译器不够聪明,无法理解第一个循环等效于第二个循环并生成更高效的(字节)代码。 在更复杂的情况下,即使最聪明的编译器也不可能知道。 如果您绝对需要此优化,则必须通过显式使用StringBuilder
手动引入它。
快速回答是性能:当您使用本机String类时,它会运行不可变的字符串,这意味着在您编写时
String line = "java"; String sufix = " is awesome"; line = line + sufix;
它将创建两个字符串“java”和“很棒”,而不是创建一个新的第三个字符串“java is awesome”来自前两个(“java”和“很棒”),后者很可能被垃圾收集器删除(因为他们不再在app中使用)。 这是一个缓慢的解决方案。
更快的解决方案是StringBuffer类的设备,它通过智能算法提供缓冲区(从名称中可以明显看出)用于合并字符串,因此在连接过程中不会删除初始字符串。
如果您正在编写单线程应用程序(多个线程访问同一对象时不会出现并发问题),最好应用StringBuilder,它比初始StringBuffer类具有更快的性能。