StringBuilder原理

1、StringBuilder和StringBuffer区别

其实StringBuilder和StringBuffer用法都是一样,几乎没啥区别,我比较常用StringBuilder。

但是说它们之间到底有没有区别,那肯定是有的。

StringBuffer的大多数方法都是用synchronized 修饰的,所以StringBuffer是线程安全的,但是就因为它被修饰了,所以StringBuffer的效率也是比StringBuilder底的。

2、要研究一下StringBuilder的原理就要先看看StringBuilder的源码。

先new个StringBuilder对象:

StringBuilder sb = new StringBuilder();

StringBuilder的定义,它定义了char的数组,这个数组长度是可变,它的长度就是count:

char[] value;
int count;

StringBuilder的构造方法,默认就是创建16的字符数组,也就是16个字节的大小:

public StringBuilder() {
    super(16);       
}

public StringBuilder(CharSequence seq) {
    this(seq.length() + 16);
    append(seq);       
}

StringBuilder的append的方法:

private StringBuilder append(StringBuilder sb) {
    if (sb == null)
        return append("null");
    int len = sb.length();
    int newcount = count + len;
    if (newcount > value.length)
        expandCapacity(newcount);
    sb.getChars(0, len, value, count);
    count = newcount;
    return this;
}

当append字符串的时候,首先会判断sb是否为空,如果不为空就获取sb的长度和StringBuilder已经拼接的字符串长度之和,也就是newcount,如果newcount大于了字符串数组(value)的长度,那么就使用expandCapacity扩充容量。最后使用sb.getChars()将新添加的字符串添加到字符串数组(value)中,并将newcount的值赋予count。

ensureCapacityInternal方法又调用了expandCapacity方法:

private void ensureCapacityInternal(int minimumCapacity) {
    if (minimumCapacity - value.length > 0)
        expandCapacity(minimumCapacity);
}

private 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);
}

先扩充16*2+2字节的容量(34字节),然后判断新扩充的字节是否大于StringBuilder的拼接字符串的长度(新添加的+已经有的字符串的长度),如果小于的话,那么新扩充的长度newCapacity就赋予StringBuilder的拼接的字符串的长度。如果newCapacity<0说明oom异常了(内存不够用了),那么这时候newCapacity = Integer.MAX_VALUE。最后在把字符串数组value的内存扩充。

猜你喜欢

转载自blog.csdn.net/AlbenXie/article/details/89739172
今日推荐