一、认识String
String类型是不可变类型,为了保持文章的独立性,还是拿出来这个老掉牙的例子:
在这里我们一开始给变量a赋值为“张三”,后来又赋值为"李四",是不是有个疑问,不是说String类型不可变嘛,在这里怎么变了,想要解决这个问题,我们还要深入String源码。下面是jdk1.8_171中String类型的一部分源码:
这里最核心的就是这个value字符串数组。也就是说我们的String的内容其实是被分割成了一个一个字符保存在了value数组当中,而且我们的String类型是final类型,value也是final类型,这就意味着我们再被集成和修改了。但是为什么我们还可以对上述的a对象赋值了两次呢?下面用一张图你就明白了。
也就是说我们的a对象其实没有改变,改变的是value数组指向的内容,因为value是数组也是引用类型,所以指向的内容可以随之改变,而且每一次赋值一个字符串,都会在内存中创建一个新的对象。当然了也有办法可以改变String类型,比如通过反射。其实通过上面的图相信也应该能明白为什么有了String还需要StringBuilder和StringBuffer。那是因为String每一次增删改的操作都是在内存中创建了一个新的字符串,如果增删改的操作很多,那对我们的内存将造成极大的浪费,为此还需要StringBuilder和StringBuffer去解决这个问题。
二、StringBuilder和StringBuffer
StringBuilder和StringBuffer是可变的,也就说我们的增删改都是在原字符串的基础上操作的,操作次数再多内存也不会被白白的浪费,那他们俩又有什么区别呢?
StringBuffer是线性安全的,支持并发操作,适合多线程。
StringBuilder线性不安全,不支持并发操作,适合单线程。
也就是说他们俩区别就在于支不支持并发操作,使用上基本上类似,知道上面的区别之后就可以根据自己的业务需求来决定具体使用哪一个。这里就以StringBuffer为例说明一下吧。
1、构造方法
2、增删改操作
三、三者之间的性能测试
在这里其实就是对于其基本操作谁的效率最快的问题。
第一步:测试String执行1万次增加操作
第二步:测试StringBuilder执行1万次增加操作
第四步:测试一下:
这个结果其实已经很明显了:
StringBuilder 和StringBuffer >的效率远远大于String。因为这里是在单线程中去测试的,所以StringBuilder的时间比StringBuffer的稍微少一点,但是多线程可能就不一定了。所以他们两者其实是没法比较的。