一篇文章快速搞懂String、StringBuffer和StringBuild的区别!
String、StringBuffer和StringBuild到底有哪些的区别?
总结 :
- 可变性:
String是字符串常量,是不可变的,StringBuild、StringBuffer是 可变字符序列 - 执行速度:
StringBuild > StringBuffer > String - 安全性能:
String、StringBuffer线程安全,StringBuild非线程安全 - 适用场景:
String,少量字符串操作的情况
StringBuffer,多线程中字符串缓冲区进行大量操作的情况
StringBuild,单线程中字符串缓冲区进行大量操作的情况
分析:
一、可变性的区别
- String被final修饰,不可变,相当于字符串常量,字符数组char value[ ] 被final修饰,源码如下:
public final class String implements java.io.Serializable,Comparable<String>,
CharSequence {
private final char value[];
......
}
- StringBuffer和StringBuild都是继承同一抽象类AbstractStringBuilder类,且char[ ] value 没有被final修饰,都是可变的,源码如下:
abstract class AbstractStringBuilder implements
Appendable, CharSequence {
char[] value;
......
}
二、执行速度的区别
- String对象是不可变的,每次对String对象的操作都会生成新的String对象,改变引用,虽然原来的String对象会被回收,但是还是造成了内存资源的浪费和JVM的线程系统开销。
如下代码,虽然输出的是 "abcdef" ,过程却并不是直接拼接,而是先创建了StringBuild对象,再调用append()方法,最后调用toString()方法创建新的字符串对象 s3,来包含修改后的字符串内容,所以String速度最慢,时间复杂度为O(n^2)。
public class Dome03 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "def";
String s3 = s1 + s2;
System.out.println(s3);
}
}
- StringBuild和StringBuffer继承同一抽象类,方法基本一样,都是可变字符串,可以直接对对象本身进行操作,不需要生成新的对象、改变对象引用,所以速度都比String快
- StringBuild之所以比StringBuffer快的原因,是因为StringBuffer大部分方法都加了synchronized同步锁,保证了安全的同时,速度自然会慢一点,所以,String Buffer速度快,StringBuild最快且时间复杂的为O(n),远优于O(n^2)。
三、安全性能的区别
- String是字符串常量,不可变,也就是线程安全
- StringBuffer也是线程安全的,因为大部分方法都有synchronized 同步锁,部分底层源码如下:
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
public synchronized int length() {
return count;
}
public synchronized int capacity() {
return value.length;
}
- StringBuild是线程不安全的,因为StringBuild是可变字符串数组,而且没有synchronized关键字,部分底层源码如下:
public StringBuilder(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public StringBuilder append(String str) {
super.append(str);
return this;
}
四、使用场景
一般来说,String适用于少量的字符串操作的情况,StringBuilder适用于单线程下在字符缓冲区进行大量操作的情况,StringBuffer适用多线程下在字符缓冲区进行大量操作的情况,当然了,StringBuffer的执行速度并不比StringBuild慢多少,而且还保证了线程安全,所以还是比较常用。