StringBuilder与StringBuffer并非是数据类型,而是操作字符串的工具类,它们的出现是为了便捷操作String及作为共享变量时的多线程处理优化。更多内容详见公众hao:云水致诚
异同点分析如下:
1、JDK5开始,String使用+拼接字符串时,底层会自动创建StringBuilder,以优化字符串拼接所耗费的内存资源。
2、AbstractStringBuilder
这两个工具类都继承了基类AbstractStringBuilder,通过其中的char[] value字符数组来存储通过append添加的字符串。
3、默认字符数组大小相同
默认的字符数组容量大小均为16,当通过append添加字符串时,会通过str.length()来计算需要拓展的字符数组大小。
4、多线程安全处理
如果涉及到线程安全,我们使用StringBuilder存放共享的字符串,这有可能被多个线程同时访问操作,所以可能出现读写不一致问题。针对这个问题,提供了StringBuffer加同步锁synchronized方式来保证同时只能有一个线程操作共享变量,其它线程需要等资源锁被释放后才能接手,在这期间会被阻塞等待。StringBuilder是非线程安全的,所以实际使用时,非共享的字符串操作建议使用StringBuilder。
5、性能效率问题
StringBuffer是线程安全的,是通过同步锁来阻塞其它线程同时操作共享变量,所以会涉及到阻塞,这会影响程序的执行效率和系统吞吐,不建议用在操作频次较大的共享变量,一般可使用Concurrent系列的容器来替代处理。
StringBuilder是非线程安全的,存在线程安全问题,但它的执行效率要高于StringBuffer,所以日常使用时,不存在线程安全问题时,优先使用它,而不要乱用StringBuffer。
4、转为String
StringBuilder和StringBuffer都通过toString()将存储在char[] value中的字符数组转为String,具体是通过new String(…)方式将char[]转为String,略有不同的是StringBuffer的toString()同样用了synchronized同步锁来保证线程安全,同时保存了一份char[] value的副本,放在了toStringCache字符数组中,当使用toString()转为String时,因为考虑到多线程问题,所以通过副本toStringCache转为String,因为这个副本是线程安全的。
5、常用API
append、reverse、replace、delete、toString及length等。
6、使用场景
非线程安全情况下:
A、使用StringBuffer替代String和StringBuilder操作字符串,以牺牲一定性能来保证数据安全。
B、若能确认线程安全,优先使用StringBuilder,因为它的性能要高于StringBuffer的性能。
线程安全情况下:
A、循环中要使用StringBuilder拼接字符串;
B、JDK5开始,String使用+拼接字符串时,底层自动使用StringBuilder来优化处理字符串拼接,以减少内存资源损耗。