StringBuffer与StringBuilder分析比较

可变性

StringBuilder与StringBuffer都继承自AbstractStringBuilder抽象类,说明线程安全不安全都是在继承之后实现的。在AbstractStringBuilder中维护一个数组,但是不同于String类中,代码如下:

/* The value is used for character storage.  */
    char[] value;

String类中为

/** The value is used for character storage. */
    private final char value[];
  • 使用final关键字修饰后,即创建对象后 ,value指向的地址不能再改变。
  • 同时,String内中也没有提供改变value[]数组中值得方法,因此不可变。
  • 但是在StringBuffer与StringBuilder中维护的char[] value,没有final修饰,同时,类中还有改变值得方法,因此,可变。

核心方法

append方法

调用StringBuilder,使用较多的方法,主要是向创建的StringBuilder中添加元素。 针对不同的输入情况,重载了许多append方法,根据使用情况自己调用就行。


容量扩展expandCapacity(int minimumCapacity)

在StringBuilder中,也涉及到动态扩容,这里的扩容不同于ArrayList中的扩容。StringBuilder初始化时,可以直接设定容量,设定值,即为在类中创建数组的容量大小。不设定,默认的容量为16测试代码如下:

public static void main(String[] args) {
		// 容量
		StringBuilder sb1 = new StringBuilder(12);
		System.out.println(sb1.capacity());   // 12
		StringBuilder sb2 = new StringBuilder(20); 
		System.out.println(sb2.capacity());   // 20
		StringBuilder sb3 = new StringBuilder(); 
		System.out.println(sb3.capacity());   // 16
	}

当数组容量超出初始容量时,再添加元素,会进行扩容。当添加元素的个数加上已经存在的元素个数大于当前容量时,会调用expandCapacity()方法,进行扩容。源码如下:

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);
}
// 测试
	public static void main(String[] args) {
		// 容量
		StringBuilder sb1 = new StringBuilder(12);
		System.out.println(sb1.capacity());   // 12
		
		for(int i = 0; i < 12; i++)
		{
			sb1.append(i);
		}
		System.out.println(sb1.capacity());  // 26  (12 * 2 + 2)
	}
  • 新的容量,直接将原来容量扩大两倍再加上2
    因此26 = 12 * 2 + 2
    至于为什么采用这样的方式,还不明白。
  • 在Arrays.copyOf()方法里,将旧数组copy至新容量的新数组,是又创建了一个新的数组。因为数组容量一旦设定,是不能再改变的。

StringBuilder与StringBuffer比较

  • 线程安全
    StringBuilder线程不安全,StringBuffer线程安全, 若多线程使用,涉及到线程安全使用StringBuffer。

  • 执行效率问题
    StringBuilder > StringBuffer > String StringBuilder与StringBuffer类似,StringBuffer确保了安全,效率相比StringBuilder低。
    对于String对象,进行多次添加,会创建多个对象,因此效率会相对低。
    但以上分析也不绝对,因为添加次数的多少及方式,也会影响结果,所以仅供参考

StringBuilder与String

  • StringBuilder可变
    StringBuilder类中,维护了一个char value[],为默认修饰符的数组,能被子类访问,或者子类与父类在同一个包下可以访问。但是StringBuilder类,使用了final修饰,不可被继承。在StringBuilder内部,提供了修改数组value[]值的方法,所以StringBuilder可变。
  • String不可变
    String类中,维护一个使用private,final修饰的数组value[],因此是私有的,不可变的,同时String类中也没有提供修改数组value[]的方法,因此,不可变。

具体String类相关可参考:String类源码解析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值