拼接字符串有很多种方式,其中最常用的有4种,下面列举了这4种方式各自适合的场景。
-
+运算符:如果拼接的都是字符串直接量,则适合使用 + 运算符实现拼接;
-
StringBuilder:如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder;
-
StringBuffer:如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;
-
String类的concat方法:如果只是对两个字符串进行拼接,并且包含变量,则适合使用concat方法;
扩展
采用 + 运算符拼接字符串时:
-
如果拼接的都是字符串直接量,则在编译时编译器会将其直接优化为一个完整的字符串,和你直接写一个完整的字符串是一样的,所以效率非常的高。
-
如果拼接的字符串中包含变量,则在编译时编译器采用StringBuilder对其进行优化,即自动创建StringBuilder实例并调用其append()方法,将这些字符串拼接在一起,效率也很高。但如果这个拼接操作是在循环中进行的,那么每次循环编译器都会创建一个StringBuilder实例,再去拼接字符串,相当于执行了 new StringBuilder().append(str),所以此时效率很低。
采用StringBuilder/StringBuffer拼接字符串时:
-
StringBuilder/StringBuffer都有字符串缓冲区,缓冲区的容量在创建对象时确定,并且默认为16。当拼接的字符串超过缓冲区的容量时,会触发缓冲区的扩容机制,即缓冲区加倍。
-
缓冲区频繁的扩容会降低拼接的性能,所以如果能提前预估最终字符串的长度,则建议在创建可变字符串对象时,放弃使用默认的容量,可以指定缓冲区的容量为预估的字符串的长度。
采用String类的concat方法拼接字符串时:
-
concat方法的拼接逻辑是,先创建一个足以容纳待拼接的两个字符串的字节数组,然后先后将两个字符串拼到这个数组里,最后将此数组转换为字符串。
-
在拼接大量字符串的时候,concat方法的效率低于StringBuilder。但是只拼接2个字符串时,concat方法的效率要优于StringBuilder。并且这种拼接方式代码简洁,所以只拼2个字符串时建议优先选择concat方法。