StringBuilder 和 常用容器初始化容量--性能--详解

时间:2021-05-23 19:34:04
StringBuilder 和 常用容器初始化容量时尽量定初始化容量,有助于提高性能。

分析:

StringBuilder StringBuffer 与ArrayList对象一样都是可变容量的。

底层实现都是char[] ,以数组形式实现的。

/**
* The value is used for character storage.
*/
char[] value;
大家都知道数组是定长的(确定了长都就不可改变的),那么他是如何实现变长的呢,看下面源码

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;
}
/**
* This method has the same contract as ensureCapacity, but is
* never synchronized.
*/
private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    //判断容量是否够用
    if (minimumCapacity - value.length > 0)
        expandCapacity(minimumCapacity);
}
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
   //每次扩容使原有的2倍加2
   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);
}

看完上面的源码,我们知道容量不够用了就重新创建数组(也就是重新分配内存空间),这些操作都是耗时间和资源的的,如果我们在初始化时定了一个接近的容量,速度会有一定的提升
StringBuffer,ArrayList 等和这个扩容方法也是大同小异,所以我们一定要重视初始化容量的问题。