StringBuffer与StringBuilder

StringBuffer与StringBuilder

StringBuffer与StringBuilder

一、相关概念
二、StringBuffer
三、String、StringBuffer、StringBuilder效率对比
一、相关概念

StringBuffer:

1.线程安全 在所有方法上都加了同步锁(synchronized) 效率低

2.可变序列

3.JDK1.0

4.char[] value 底层实现 不没有加final修饰,说明是可变

5.与StringBuilder继承了同一个父类AbstractStringBuilder

6.支持方法链


StringBuilder:

1.线程不安全 效率高

2.可变序列

3.JDK1.5

4.char[] value 底层实现 不没有加final修饰,说明是可变

5.与StringBuffer继承了同一个父类AbstractStringBuilder

6.支持方法链

二、StringBuffer与StringBuilder
StringBuffer buffer = new StringBuffer() 实例对象();//创建StringBuffer() 实例对象

1.以这种形式创建的new StringBuffer() ,StringBuffer()会通过无参构造器创建一个16大小的char数组,默认16

public StringBuffer() {
	super(16);//调用父类的构造,并传入数值
}
AbstractStringBuilder(int capacity) {
	value = new char[capacity]; //获取数值,创建对应数值大小的数组
}

StringBuffer buffer = new StringBuffer(13);//创建StringBuffer() 实例对象,并传入数值

1.以这种形式创建new StringBuffer(13) ,StringBuffer(13)会通过有参构造器认创建一个指定数值大小的char数组

public StringBuffer(int capacity) {
	super(capacity);
}
AbstractStringBuilder(int capacity) {
        value = new char[capacity];
}

StringBuffer buffer = new StringBuffer("abc");

1.以这种形式创建的new StringBuffer(“abc”); new StringBuffer(“abc”)会通过构造器创建一个“abc”的长度加16创建一个char数组

public StringBuffer(String str) {
	super(str.length() + 16);
	append(str);
}

StringBuffer buffer = new StringBuffer("abc");
buffer.append("sds");

那么假如使用append进行字符拼接的长度大于char数组的长度怎么办?可以看一下java底层是怎么解决的。

 public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len); //获取原有的数据长度+append进来的数据长度
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

ensureCapacityInternal(count + len); //获取原有的数据长度+append进来的数据长度

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code			//minimumCapacity==获取原有的数据长度+append进来的数据长度
    if (minimumCapacity - value.length > 0) {  //判断minimumCapacity-value.length()>0 如果大于说明数组容量不足,需要扩容
		value = Arrays.copyOf(value,
		newCapacity(minimumCapacity));
        }
}
private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2; //扩充原数组的两倍+ 2
        if (newCapacity - minCapacity < 0) {//特殊情况,假设你新拼接的字符串长度太长已超过扩容后的长度,那么干脆用原有数组的长度+新数据的长度的和
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)//如果向左移超出了范围,就可能变成负的了
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

StringBuffer buffer = new StringBuffer();
buffer.append('a');
buffer.append('c');

1.使用append拼接的是字符数据,那么底层实现就是

value[0]='a'
value[1]='c'

2.具体实现就是使用count做计数

 public AbstractStringBuilder append(char c) {
	ensureCapacityInternal(count + 1);
	value[count++] = c;
	return this;
 }

3.那么通过使用StringBuffer().length()方法获取的长度就是在获取count的值

StringBuffer buffer = new StringBuffer("abc");
System.out.println(buffer.length());//3

三、String、StringBuffer、StringBuilder效率对比
String str1 = "";
        StringBuffer stringBuffer = new StringBuffer();
        StringBuilder stringBuilder = new StringBuilder();

        //String
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            str1 += i;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("String花费时间:" + (endTime - startTime));

        //StringBuffer
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuffer.append(String.valueOf(i));

        }
        endTime = System.currentTimeMillis();
        System.out.println("stringBuffer花费时间:" + (endTime - startTime));

        //StringBuilder
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuilder.append(String.valueOf(i));

        }
        endTime = System.currentTimeMillis();
        System.out.println("stringBuilder花费时间:" + (endTime - startTime));
String花费时间:939
stringBuffer花费时间:4
stringBuilder花费时间:2

可以看出来String因为是不可变的所以每次改变都需要去常量池创建,效率最低

而StringBuffer为保证线程安全,给append加了 锁,所以效率比StringBuilder低一点

StringBuilder效率最高,可以看情况决定使用哪种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值