JAVA中的StringBuilder和StringBufferString的扩容机制

JAVA中的StringBuilder和StringBufferString的扩容机制


StringBuilder 和 StringBuffer

StringBuilder 和 StringBuffer 是 Java 中用于可变字符串操作的类,它们都继承自 AbstractStringBuilder。它们的主要区别在于 StringBuffer 的方法是同步的,而 StringBuilder 的方法不是,因此 StringBuilder 在单线程环境下效率更高。在扩容机制上,StringBuilder 和 StringBuffer 基本上是一致的。


提示:以下是本篇文章正文内容,下面案例可供参考

源码分析

StringBuilder 和 StringBuffer 都继承自AbstractStringBuilder,StringBuilder 和 StringBuffer 的扩容机制是一样的,因此分析一个即可。

 * @see         java.lang.String
 * @since       1.5
 public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
  * @see     java.lang.String
 * @since   JDK1.0
 * public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

接下来看一下String Builder底层的一些方法。

1.StringBuilder的无参构造方法

StringBuilder的无参构造初始容量为:16,下图为无参构造方法的源码
它调用了父类的有参构造方法。

  /**
     * Constructs a string builder with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuilder() {
        super(16);
    }

下图为父类的有参构造方法,此时父类构造方法中的int capacity参数为16,也就是它的初始容量。value为它的成员变量,对成员变量进行了初始化操作,value底层为char类型的数组,没有被final修饰,可以改变指向。

 /**
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

2.StringBuilder的有参构造方法

有参构造分两种:
下图为第一种有参构造方法,参数为int值,可以根据需要指定数组的初始化容量。设置int capacity的数值。

 public StringBuilder(int capacity) {
        super(capacity);
}

第二种有参构造方法,其中参数为字符串类型。它调用了父类的有参构造方法,里面的参数为字符串的长度+初始长度16。接着调用了append方法,
进入append方法,又调用父类的append方法,返回值为字符串类型。

  public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
   public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

有参和无参扩容方法都一样的。都是从当前容量开始扩容。一次追加长度超过当前容量,则会按照当前容量2+2 扩容一次。一次追加长度不仅超过初始容量,而且按照当前容量2+2 扩容一次也不够,其容量会直接扩容到与所添加的字符串长度相等的长度。之后再追加的话,还会按照当前容量*2+2进行扩容。

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

    private int hugeCapacity(int minCapacity) {
        if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
            throw new OutOfMemoryError();
        }
        return (minCapacity > MAX_ARRAY_SIZE)
            ? minCapacity : MAX_ARRAY_SIZE;
    }

代码示例

1、一次添加的长度不超过16不会进行扩容

public class Test01 {
	public static void main(String[] args) {
		//无参构造初始容量为: 16
		StringBuilder a = new StringBuilder();
		a.append("abc");
		a.append("799898989");
		System.out.println(a);
		//使用StringBuilder的capacity()方法可以查看其当前容量
		System.out.println("a的容量为:"+a.capacity()+" a的长度为:"+a.length());
    }
}

此时输出结果为
在这里插入图片描述

2、一次追加字符串的长度超过了16,其容量会按照:当前容量2+2 进行扩容,即:162+2=34

public class Test01 {
	public static void main(String[] args) {
		//无参构造初始容量为: 16
		StringBuilder a = new StringBuilder();
		a.append("abc");
		a.append("799898989");
		a.append("323232");
		System.out.println(a);
		//使用StringBuilder的capacity()方法可以查看其当前容量
		System.out.println("a的容量为:"+a.capacity()+" a的长度为:"+a.length());
	}
}

此时输出结果为
在这里插入图片描述

3、若一次追加的字符串长度超过了扩容一次之后的长度,其容量会直接扩容到与所添加的字符串长度相等的长度。

public class Test01 {
	public static void main(String[] args) {
		//无参构造初始容量为: 16
		StringBuilder a = new StringBuilder();
		a.append("2626ddfdvfgfgbgfgfdgdgdvffdgfgfdgfdgfdgfd");
		System.out.println(a);
		//使用StringBuilder的capacity()方法可以查看其当前容量
		System.out.println("a的容量为:"+a.capacity()+" a的长度为:"+a.length());
	}
}

此时的输出结果为
在这里插入图片描述

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值