场景应用:说说你对字符串拼接的理解

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了场景应用:说说你对字符串拼接的理解相关的知识,希望对你有一定的参考价值。

文章目录

四种字符串拼接方式

首先是字符串拼接的方式,拼接字符串有很多种方式,其中最常用的有4种,下面列举了这4种方式各自适合的场景。

  1. + 运算符:如果拼接的都是字符串直接量,则适合使用 + 运算符实现拼接;

  2. StringBuilder:如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder;

  3. StringBuffer:如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;

    可以看到SringBuffer内部就是用synchronized关键字实现的:

  4. 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对象,这个对象会被保存在堆内存中。并且,堆中对象的数据会指向常量池中的直接量。

以上是关于场景应用:说说你对字符串拼接的理解的主要内容,如果未能解决你的问题,请参考以下文章

说说你对Node.js 的理解?优缺点?应用场景?

[Redux/Mobx] 什么是redux?说说你对redux的理解?有哪些运用场景?

前端:如何理解 JS 的作用域和作用域链?说说闭包的两个应用场景

《我要进大厂系列 二》-说说你对CAS理解

[react] 说说你对Error Boundaries的理解

面试题2020-03-31说说你对ThreadLocal的理解