一、三者区别
String每次增加数据都会开辟新空间,存储数据,然后将之前的那一块空间通过GC进行回收
StringBuilder是可变长度的,数据增加是直接在现有的空间中进行操作。但是它不是线程安全的。
StringBuffer也是可变长度的,数据增加也是直接在现有的空间中进行操作。但是它是线程安全的。
(StringBuilder和StringBuffer每次都会多开辟一些空间,避免每次往字符串后面添加字符时都要开辟空间,新建对象。只有当开辟的空间已经不够用时,才会重新开辟一个新空间。有点像是以空间换时间。String和StringBuilder的区别很像定长数组和动态数组的区别。)
二、源码分析
1、StringBuffer
1.1、构造方法一——用户可自己指定StringBuilder的初始大小。
根据实际情况来指定大小的话可以减少开辟空间的次数,也可以减少空间的浪费
/**
* Constructs a string buffer with no characters in it and
* the specified initial capacity.
*
* @param capacity the initial capacity.
* @exception NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
/*
* 构造一个没有字符的空字符串,大小为capacity。
* 如果capacity小于0会返回一个异常.
*/
public StringBuffer(int capacity) {
super(capacity);
}
1.2、构造方法二——默认大小的构造方法(输入的字符串长度+16)
/**
* Constructs a string buffer initialized to the contents of the
* specified string. The initial capacity of the string buffer is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
1.3、普通方法——synchronized(线程安全的)
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}
1.4、容量扩展方法
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
/*
* 当原有容量不够时,对其进行扩展(乘以2再加上2)
*
*/
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
2.StringBuilder除了普通方法没有加synchronized关键字,其他都和StringBuffer差不多。
三、使用场景
String针对的是少量字符串的操作。
当字符串较多,并且是多线程时,应当用StringBuffer。
当字符串较多,并且是单线程时,应当用StringBuilder。
四、运行速度
StringBuilder>StringBuffer>String