关于StringBuilder和StringBuffer扩容的问题

2022-07-16 11:55:35

首先,查看一下二者的继承体系,都继承自抽象类AbstractStringBuilder

下面是AbstractStringBuilder类的有参数构造器

AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
在新建StringBuilder和StringBuffer的会后都会调用父类的构造器,默认长度为16
public StringBuilder() {
        super(16);
    }
public StringBuffer() {
        super(16);
    }
有参数构造器
public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
再说他他们的扩容:

使用append()方法在字符串后面追加方法的时候,如果长度超过了字符串的存储空间,就需要扩容,扩容的方式就是构建新的字符串将新的复制过去,在进行字符串append添加的时候,会先计算添加后字符串大小,传入一个方法:ensureCapacityInternal 这个方法进行是否扩容的判断,需要扩容就调用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);
    }
先尝试将容量夸大至2倍+2,如果还是不够,则直接扩容至需要的大小,


最后上测试代码

public static void main(String[] args) {
        //1:调用无参数构造器
        StringBuffer str = new StringBuffer();
        str.append("12345");
        System.out.println(str.capacity());//16
        System.out.println(str.length());//5
        str.append("67890123456");
        System.out.println(str.capacity());//16
        System.out.println(str.length());//16
        str.append("1");
        System.out.println(str.capacity());//34
        System.out.println(str.length());//17
        //2:调用有参数构造器
        str = new StringBuffer("123");
        System.out.println(str.capacity());//19
        System.out.println(str.length());//3
    }
  • 作者:dong900923
  • 原文链接:https://blog.csdn.net/JAVA__BEST_LANGUAGE/article/details/53333491
    更新时间:2022-07-16 11:55:35