美文网首页
五种字符串拼接的区别

五种字符串拼接的区别

作者: 小月半会飞 | 来源:发表于2019-03-04 12:27 被阅读0次

String +=:将s+=”a”生成字节码,反编译之后,应该是一下代码:
String s=(new StringBuilder()).append(s).append(“a”).toString();
也就是说使用+=的时候是先将String转成了StringBuilder,使用其的append方法进行处理,从内存分配上来讲,又是新给了一个String,然后指向这个新的字符串,与concat相比每次不仅新New出来一块新的内存,并且还new了一个新的StringBuilder对象

StringBuffer:StringBuffer对象是可以修改和扩充的,直接在堆里面给分配一块内存,每一次使用append方法的时候,就在这个内存块里面在添加一个a,所以相对String要快一些,但是与StringBuilder相比又要慢一些,这是因为StringBuffer是线程安全的,它的append方法是synchronized声明的(意思是这个方法约么全部执行成功,要么全部不成功),是线程安全的。通俗来讲就是StringBuffe的append有三个步骤,lock,临界区,unclock这三步,由于StringBuffer是多线程的,所以在for循环使用append的时候会有多个线程都分配到项目,在cpu切换内存执行的时候有可能线程1正在临界区添加数据 ,但是还未进入到解锁阶段,这个时候如果cpu切换到另一个线程2执行,线程2就会发现线程1没有解锁,所以线程2就会等待,等待下一次cpu切换到线程1 继续执行,直到线程2发现线程1解锁,那么线程2就会先加锁,以确保自己能够执行完成,StringBuilder的append方法不是synchronized声明的,所以没有加锁和解锁的过程,所以也就没有线程2的等待过程,所以会相对快一些,但是线程是不安全的,容易造成数据丢失

StringBuilder: StringBuilder的append方法是直接进入临界区,当cpu切换到当前程序的时候,假如当前cpu第一次执行这个程序,第一次进入append的for循环的时候会讲数据写进去,然后更新一下count,表示已经使用的字符个数,也可以当作下标index来看,然后当下一次cpu切换到线程2的时候,就会往新的index里面放数据,这种情况是基于前面那个线程把数据更行完成并且更新了新的index,但是有的时候当cpu切换到一个新的线程的时候他有可能前面那个线程append的时候,数据填写了,Index没有更新,这个新的线程执行append方法的时候酒还是会在之前的Index的位置去添加数据,这就造成了之前那个线程添加的数据丢失,所以StringBuilder是线程不安全的,但是因为没有等待的过程所以相对较快,从代码上来讲StringBuilder本身有一个字符数组,每一次append就是往这个数组里面添加数据,同理StringBuffer也是一样的

concat:是final修饰的类,是不可以被继承以及被修改的,所以每一次s+=”a”的时候事实上是在每一个常量池里面新给一个内存块,每一次的+=都会给一个新的内存,一个新的地址,然后这个变量s指向新的变量,如此十万次就有了十万给内存块被new出来,所以速度相对较慢,从代码上来讲就是每一次先创建一个字符串数组,长度是两个待拼接字符串长度之和,再将两个字符串的值复制到这个字符数组中,并且使用这个数组创建一个新的String对象并且返回,每次都new一个新的String,源代码如下:
public String concat(String str){
int otherLen=str.length();
if(otherLen ==0){
return this;
}
Int len=value.length;
Char buf[]=Arrays.copyOf(value,len+otherLen);
Str.getChars(buf,len);
Return new String(buf,true);
}

StriingUtils.join:与String +=类似,也是使用了StringBuilder来进行操作,但是其中还有很多其他操作,所以耗时比较长,其实StriingUtils.join更加擅长处理字符串数组的拼接

所以以上五个方法执行从0个到十万个a的添加,时间上的长短排序如下:
StringBuilder < StringBuffer < concat < String += < StriingUtils.join

相关文章

  • mybatis--获取参数的方法

    获取参数的两种方式:#{}与${} {}与${}区别: {}使用字符串拼接的方式拼接sql,若为字符串类型或日期类...

  • Mybatis

    mybatis中#和$的区别 $直接与SQL语句进行拼接,#以字符串进行拼接,即加“”; #{}会经过预编译, ...

  • String

    String与StringBuilder的区别 什么是StringBuilder 可以完成字符串的拼接;需要引入S...

  • R 包学习 - stringr()

    stringr: R 语言字符串处理包 字符串拼接函数str_c: 字符串拼接。str_join: 字符串拼接,同...

  • 字符串

    遍历 拼接 字符串拼接格式化 字符串的截取

  • Swift5.0 字符串(String)详解

    1.字符串拼接 + 拼接 \() 拼接 2.字符串是否为空判断 3.字符串长度 4.字符串比较 == > < 5....

  • PHP 篇 --- 2021-08-31

    基础篇 Get 和 POST 的区别(1). 显示有区别get方法是将字符串拼接在地址栏后面可以看见; 而post...

  • 字符串api

    字符串 增 concat() //拼接任意字符串,并返回拼接后的字符串 加号 ➕ 同上 字符串 ...

  • go语言string之Buffer与Builder

    操作字符串离不开字符串的拼接,但是Go中string是只读类型,大量字符串的拼接会造成性能问题。 字符串拼接的方式...

  • Python 字符串详解

    字符串替换 字符串拼接 1.两个字符串拼接 2.打印拼接 字符串按照字符切割 字符串比较 字符串长度 字符串是否包...

网友评论

      本文标题:五种字符串拼接的区别

      本文链接:https://www.haomeiwen.com/subject/cegbuqtx.html