Stringbuffer源碼分析

本文用於分析當建立StringBuffer對象後,調用append方法時,StringBuffer內部是如何擴容的數組

一、建立StringBuffer對象,並調用append方法,這是咱們開發時常常作的app

StringBuffer sb = new StringBuffer("abc");//原來數據的長度:3個字符
sb.append("defghijklmnopqrst");//新增長數據的長度:17個字符ui

二、查看append方法的源碼
public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }this

上面的代碼能夠知道它調用的是父類AbstractStringBuilder的append方法,接着進入父類的append方法code


三、分析父類的append方法對象

//str-->"defghijklmnopqrst"
public AbstractStringBuilder append(String str) {
    //新增長的數據爲null則直接返回字符串"null"
        if (str == null) str = "null";
        int len = str.length();//新增長數據的長度爲:17
        ensureCapacityInternal(count + len);//擴容:count+len=3 + 17
        str.getChars(0, len, value, count);//將原來的數據複製到擴容後的數組中
        count += len;
        return this;
    }索引

從上面能夠看出append方法調用了ensureCapacityInternal方法和str.getChars(0, len, value, count);,這裏咱們用3.1來分析前者(擴容操做),3.2來分析後者(將數據複製到擴容後的數組中)ci

=================================================開始擴容=================================================開發

3.一、ensureCapacityInternal()字符串

//int minimumCapacity = 20
private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code:判斷是否須要擴容,也就是說原來的capacity是否足夠大
        if (minimumCapacity - value.length > 0) //20-19=1,1>0
            expandCapacity(minimumCapacity);
    }

上面的代碼又調用了expandCapacity方法,咱們用3.1下面的子標題來進行一步步分析
3.1.1 expandCapacity

void expandCapacity(int minimumCapacity) { //int minimumCapacity=20
        int newCapacity = value.length * 2 + 2; //新的容量capacity=原來的長度*2+2
    //擴容後的容量-字符串實際長度<0(就是說若是擴容後還裝不下),
    //則使用字符串實際長度做爲StringBuffer的capacity
    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);
    }

3.1.1.1 Arrays.copyOf(value, newCapacity)
//copyOf方法用於建立一個新數組,新數組的長度是擴容後的長度,並將原來的值複製到新的數組中
//這裏須要注意,雖然數組是新的,可是StringBuffer仍是原來的StringBuffer
//original:StringBuffer中原來的值,也就是'abc'
//newLength:新的長度,19*2+2=40
public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

=================================================擴容結束=================================================


3.2 str.getChars(0, len, value, count);

將字符從str字符串複製到目標數組value中,這裏就是把str的全部值複製到value數組的最後面

//int srcBegin:字符串str中要複製的第一個字符的索引 //int srcEnd:字符串str中要複製的最後一個字符以後的索引 //char dst[]:目標數組 //int dstBegin:目標數組中的起始偏移量 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {         if (srcBegin < 0) {             throw new StringIndexOutOfBoundsException(srcBegin);         }         if (srcEnd > value.length) {             throw new StringIndexOutOfBoundsException(srcEnd);         }         if (srcBegin > srcEnd) {             throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);         }         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);  

相關文章
相關標籤/搜索