场景应用:说说你对字符串拼接的理解
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了场景应用:说说你对字符串拼接的理解相关的知识,希望对你有一定的参考价值。
文章目录
四种字符串拼接方式
首先是字符串拼接的方式,拼接字符串有很多种方式,其中最常用的有4种,下面列举了这4种方式各自适合的场景。
-
+
运算符:如果拼接的都是字符串直接量,则适合使用 + 运算符实现拼接; -
StringBuilder
:如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder; -
StringBuffer
:如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;可以看到SringBuffer内部就是用synchronized关键字实现的:
-
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方法。
问题深思:
两个字符串相加的底层实现是怎样的?
如果拼接的都是字符串直接量,则在编译时编译器会将其直接优化为一个完整的字符串,和你直接写一个完整的字符串是一样的。
如果拼接的字符串中包含变量,则在编译时编译器采用StringBuilder对其进行优化,即自动创建StringBuilder实例并调用其append()方法,将这些字符串拼接在一起。
String a = “abc”; ,说一下这个过程会创建什么,放在哪里?
JVM会使用常量池来管理字符串直接量。在执行这句话时,JVM会先检查常量池中是否已经存有"abc",若没有则将"abc"存入常量池,否则就复用常量池中已有的"abc",将其引用赋值给变量a。
new String(“abc”) 是去了哪里,仅仅是在堆里面吗?
在执行这句话时,JVM会先使用常量池来管理字符串直接量,即将"abc"存入常量池。然后再创建一个新的String对象,这个对象会被保存在堆内存中。并且,堆中对象的数据会指向常量池中的直接量。
以上是关于场景应用:说说你对字符串拼接的理解的主要内容,如果未能解决你的问题,请参考以下文章
[Redux/Mobx] 什么是redux?说说你对redux的理解?有哪些运用场景?
前端:如何理解 JS 的作用域和作用域链?说说闭包的两个应用场景