1. 程式人生 > >StringBuilder和StringBuffer區別以及原理

StringBuilder和StringBuffer區別以及原理

區別

其實StringBuilder和StringBuffer用法都是一樣,幾乎沒啥區別,我比較常用StringBuilder。但是說它們之間到底有沒有區別,那肯定是有的。StringBuffer的大多數方法都是用synchronized 修飾的,所以StringBuffer是執行緒安全的,但是就因為它被修飾了,所以StringBuffer的效率也是比StringBuilder底的。

StringBuilder原理

要研究一下StringBuilder的原理就要先看看StringBuilder的原始碼。

StringBuilder的定義,它定義了char的陣列,這個陣列長度是可變,它的長度就是count

char[] value;
int count;

先new個StringBuilder物件

StringBuilder sb = new StringBuilder();

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。

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

ensureCapacityInternal方法又呼叫了expandCapacity方法

oid 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的記憶體擴充。