1、String和StringBuffer、StringBuilder的区别
- 相同点
都实现了CharSequence接口,底层都是char数组
public final class String
implements java.io.Serializable,
Comparable<String>, CharSequence {}
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
- 不同点
String是字符序列不可变字符串,存储在字符串常量池中
private final char[] value; //final修饰,不可指向其他地址
StringBuffer、StringBulider是可变字符串,底层是char数组(继承自父类),初始化容量为16
public StringBuffer() {
super(16); //调用父类中的构造方法
}
StringBuffer、StringBulider的父类
abstract class AbstractStringBuilder {
char[] value; //可以看到char数组是可变的
}
2、StringBuffer、StringBuilder的区别
- 相同点
都继承自 abstract class AbstractStringBuilder{}
类
- 不同点
StringBuffer:
是线程安全的、适用于多线程操作同一个
存在字符缓冲区,toString()方法时会使用字符缓冲区(使用场景为多线程,为了提高效率)
//公开的方法上都加了synchronized
Buffer public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
//字符串缓存区,返回最后一次toString的缓存值,一旦StringBuffer被修改就清除这个缓存值
private transient char[] toStringCache;
@Override
public synchronized String toString() {
//调用toString方法时会使用最后一次toString的字符串缓冲
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBulider:
是非线程安全的,适合在单线程环境下使用,效率更高
toString()方法,每次新建一个字符串,String底层都会调用Arrays.copyOfRange()方法
public String toString() {
return new String(value, 0, count);
}
3、如何优化StirngBuilder、StringBuffer
在创建StringBuffer之前预测StringBuffer中存储的字符串数量,然后采用指定初始化容量的方式创建,减少底层数组的拷贝扩容