String、StringBuffer、StringBuilder的区别

1 篇文章 0 订阅
1 篇文章 0 订阅

String、StringBuffer、StringBuilder的区别

String与StringBuffer&StringBuilder的区别:

相同点:

三者都是处理字符串常用的类,同时,都是被final修饰的类,不允许被继承

不同点:

1. 是否可变长

String底层是一个final修饰的字符数组,因此是不可变长的

public final class String implements 
    java.io.Serializable, 
    Comparable<String>, 
    CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    //...
}

而StringBuffer&StringBuilder都继承了AbstractStringBuilder,底层是可变长字符数组

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
	//...
}
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
	//...
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;
    	//...
}
2. 实现的接口

String实现了java.io.Serializable, Comparable, CharSequence三个接口
而StringBuffer&StringBuilder只实现了Serializable、CharSequence两个接口
因此String的实例可以通过compareTo方法进行比较,而StringBuffer&StringBuilder不可以
但是StringBuffer&StringBuilder可以通过append、insert等方法对字符串进行操作,而String不可以

3. 执行速度

因为String是不可变长的字符数组,所以String的实例都是字符串常量(即String对象不可更改),而StringBuffer&StringBuilder的实例是字符串变量(对象可更改)。
因此从执行速度上看:StringBuffer&StringBuilder > String

应用场景:

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

StringBuffer与StringBuilder的区别:

相同点:

都继成了AbstractStringBuilder这个抽象父类,实现了CharSequence接口

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
	//...
}

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{
	//...
}

append方法
都是super.append(str),调用了父类AbstractStringBuilder的append(String str)方法
初始容量和扩容机制
初始容量都是16和扩容机制都是"旧容量*2+2"
初始容量:

public StringBuffer() {
	super(16);
}

public StringBuider() {
	super(16);
}

扩容:

public AbstractStringBuilder append(String str) {
	if (str == null)
	  	return appendNull();
	int len = str.length();
	ensureCapacityInternal(count + len); //扩容
   	str.getChars(0, len, value, count);
   	count += len;
 	return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
	// overflow-conscious code
    if (minimumCapacity - value.length > 0) {
	 	value = Arrays.copyOf(value,newCapacity(minimumCapacity));
 	}
}

private int newCapacity(int minCapacity) {
	// overflow-conscious code
	int newCapacity = (value.length << 1) + 2; // length*2 + 2
	if (newCapacity - minCapacity < 0) {
		newCapacity = minCapacity;
	}
	return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
		? hugeCapacity(minCapacity)
		: newCapacity;
}

底层数组
都是用char[]字符数组实现,且都是可变的,与String不同

不同点:

1. 提出时间

StringBuffer从JDK1.0就有了,而StringBuilder类是JDK1.5才提出的

2. 线程安全

StringBuffer多线程安全的,因为它相关方法都加了synchronized 关键字
StringBuilder多线程不安全

3. 速度

因为StringBuffer需要获取锁和释放锁,而所以在单线程情况下,StringBuilder性能优于StringBuffer

4. toStringCache

StringBuffer比StringBuilder多一个字段:toStringCache,用来在toString方法中进行缓存,每次append操作之前都先将toStringCache设置为null,若连续多次调用toString方法,可避免每次Arrays.copyOfRange(value, 0, count)操作,节省性能。

@Override
public synchronized String toString() {
    if (toStringCache == null) {
        toStringCache = Arrays.copyOfRange(value, 0, count);
    }
    return new String(toStringCache, true);
}

应用场景:

StringBuffer虽然是多线程安全的,但是加了synchronized,导致其效率低下。故适用于多线程下,并发量不高的场景。
StringBuilder没有加任何锁,效率高,适用于单线程场景,但同时也适用于高并发场景中,提高高并发场景下的程序响应性能,通过ThreadLocal、CAS操作等方式解决其线程安全问题。
高并发场景下,优先使用StringBuilder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值