String与StringBuilder

1.String

String一旦创建后就不会更改。

string s = "abc";
s = "123";

当s被赋值时,它并不会直接赋值,

  1. 首先会去查找字符串池,如果字符串池有这个字符串,那么直接将当前变量指向字符串池内的字符串。
  2. 如果字符串池内没有这个字符串,那么在堆上创建一块内存用于放置这个字符串,并将当前变量指向这个新建的字符串。

而是在堆上开辟空间,存放"123"这个数据,之后改变引用地址,指向"123",而原来的数据则是放在堆上等待GC。由此可见,当它进行拼接的时候,也只是创建一个空间存放新的数据,一旦数量庞大就会造成大量的GC。

为什么字符串一定要是不可变的?

  1. 线程安全。在多线程环境下,只有对资源的修改是有风险的,而不可变对象只能对其进行读取而非修改,所以是线程安全。如果字符串是可修改的,那么在多线程环境下,需要对字符串进行频繁加锁,这是比较影响性能的。
  2. 为了安全。

2.StringBuilder

这要从StringBuilder的底层开始说起,StringBuilder的底层与string一样都是字符数组(即char[]),与string被设计为不可变不同的是,StringBuilder是可变的。

当StringBuilder进行连接操作时,它会经历以下步骤:

  1. 检查当前字符数量是否大于长度,如果大于,那么对StringBuilder进行扩容。
  2. 向char[]数组后面添加字符

很显然,只有在StringBuilder长度小于添加的字符时,才会额外申请内存对char[]数组进行扩容,其他情况下,就是对数组内的元素进行变换而已,与string类型每次连接都会废弃掉一个对象相比,StringBuilder就显得更快一些了。

当然,除了连接操作,StringBuilder还支持删除、修改字符串,这当然也是根据其中的char []数组进行操作的(而字符串因为其不可变性,是不支持这些操作的)。

考虑到StringBuilder扩容也是会产生GC的,所以一般比较好的做法是,在StringBuilder创建时就根据之后的使用情况为其指定一个容量。

参考链接:https://www.cnblogs.com/duyao/p/16359850.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值