Java中String, StringBuilder, StringBuffer比较
AI摘要: 本文比较了Java中的String, StringBuilder, StringBuffer三种字符串类,指出它们在性能和线程安全方面的不同。String是不可变的,频繁修改效率低;StringBuilder是线程安全的,但效率较低;StringBuffer既线程安全又高效,但需要加锁。最后,文章还提到了Golang中处理字符串拼接的性能问题,以及与Java的对比。
String
在Java当中,String
是一个不可变类(被声明为final class),对String的任何操作都将创建一个全新的String对象,其存放地址在字符串常量池当中。
这样做的好处是线程安全,不同的线程对同一个字符串进行修改的时候,都会创建一个全新的String;缺点是在频繁修改字符串的情况下,效率偏低。
StringBuilder
在频繁对字符串进行增删改的情况中,String的效率偏低,这个时候Java中新增了StringBuilder
类(内置了append,add方法),可以原地修改字符串,效率很高,但是也带来的线程不安全的问题。
StringBuffer
StringBuffer
和StringBuilder
的区别不大,只是在每个操作方法都加了synchronized
同步关键字,所以就是一个线程安全的可修改的字符序列
总结
-
性能上
-
线程安全(带锁)— 速度慢
-
线程不安全(不带锁)— 速度快
-
-
使用场景上
-
操作数量少 —
String
-
单线程大量操作 —
StringBuilder
-
多线程大量操作 —
StringBuffer
-
-
golang对比补充:
-
最近在学习golang,同样遇到了String拼接的性能问题。Golang和Java一样,String是不可变的,频繁的凭借会创造大量的中间字符串。Golang提供了strings.Builder和Bytes.Buffer两种处理办法,两种方式的底层都是维护了一个动态可变的
[]bytes
数组。strings.builder会比bytes.Buffer稍微快一点,因为strings.builder直接将[]bytes
动态数组转化为字符串,而bytes.Buffer会重新申请一块空间存储转化出来的最终字符串。 -
在Golang中的bytes.Buffer和Java中的StringBuffer不一样,是没有加锁的
-