天天看點

JDK源碼解析---StringBuffer

文章目錄

      • 1.概述
      • 2.類圖
      • 3.屬性
      • 4.構造方法
      • 5.緩沖區的大小和内容長度
      • 6.擴容/縮容
      • 7.擷取字元/擷取代碼點
      • 8.getChars/setCharAt
      • 9.append
      • 10.删除
      • 11.替換
      • 12.截取子串
      • 13.插入
      • 14.比對
      • 15.toString

1.概述

​ StringBuffer,由名字可以看出,是一個String的緩沖區,也就是說一個類似于String的字元串緩沖區,和String不同的是,它可以被修改,而且是線程安全的。但是多個線程同時操作StringBuffer時候,對它而言隻有一個線程在進行操作是串行執行的。StringBuffer在任意時刻都有一個特定的字元串序列,不過這個序列和它的長度可以通過一些函數調用進行修改。StringBuffer會自動增加容量。

​ 所有的修改操作(增加,删除,替換)均會造成緩沖區清空,修改操作均是synchronized修飾

2.類圖

JDK源碼解析---StringBuffer

StringBuffer繼承了AbstractStringBuilder,實作或間接實作了序列化接口,字元序列接口和可追加接口。

3.屬性

  1. private transient char[] toStringCache,用于存儲傳回最後一次toString的緩存值,這是不需要序列化的。而是重寫writeObject方法,将有實際資料存儲(value)的部分進行序列化。
  2. static final long serialVersionUID = 3388685877147921107L; 序列化版本id,标明了這個StringBuffer屬于哪一個jdk版本中的。
  3. 父類的屬性
    1. char[] value;
    2. int count;

4.構造方法

  1. StringBuffer() 預設構造方法
public StringBuffer() {
    super(16);
}
           

​ 調用其父類的構造方法,初始空間為16

2. StringBuffer(int capacity)
           
public StringBuffer(int capacity) {
    super(capacity);
}
           

​ 指定大小初始化緩沖區

3. StringBuffer(String str)
           
public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
           

​ 将str字元串放入緩沖區,緩沖區的大小為str的長度+16.

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

​ 和上面差不多,不同在于一個是字元串 一個是字元序列。

5.緩沖區的大小和内容長度

  1. length() 傳回的是内容的長度
  2. capacity()傳回的是緩沖區的大小。

注意:這兩個方法都是加了synchronized修飾符

6.擴容/縮容

  1. 擴容 ensureCapacity(int minimumCapacity)

    判斷給定的參數和目前緩沖區的大小,若給的參數更大,則調用父類的擴容方法,在AbstractStringBuilder解析中有介紹。

public synchronized void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            super.ensureCapacity(minimumCapacity);
        }
    }
           
  1. setLength(int newLength) 設定長度

    首先會将緩存清空,在調用父類的setLength方法,而父類的該方法會調用擴容方法,在将空閑的位置用’\0’ 即空字元填充。

public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }
           
  1. 縮容 trimToSize()

    同樣也是調用父類的縮容方法

public synchronized void trimToSize() {
    super.trimToSize();
}
           

7.擷取字元/擷取代碼點

code point 就是unicode編碼即那個字元的16進制編碼。

  1. codePointAt(int index)

    獲得index下标對應字元的16進制編碼

public synchronized int codePointAt(int index) {
        return super.codePointAt(index);
    }
           
  1. codePointBefore(int index)

    擷取index-1下标對應字元的16進制編碼

public synchronized int codePointBefore(int index) {
    return super.codePointBefore(index);
}
           
  1. codePointCount(int beginIndex, int endIndex)

    傳入的參數為左閉右開,統計的是字元的個數

public synchronized int codePointCount(int beginIndex, int endIndex) {
    return super.codePointCount(beginIndex, endIndex);
}
           
  1. offsetByCodePoints(int index, int codePointOffset)

    從下标index的位置 偏移codePointOffset位置對應的字元代碼點傳回。

public synchronized int offsetByCodePoints(int index, int codePointOffset) {
    return super.offsetByCodePoints(index, codePointOffset);
}
           

8.getChars/setCharAt

​ 1.getChars(int srcBegin, int srcEnd, char[] dst,int dstBegin)

​ 将字元串從srcBegin開始到srcEnd-1的位置 複制到數組dst中,并從dstBegin位置開始存放。

public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
                                  int dstBegin)
{
    super.getChars(srcBegin, srcEnd, dst, dstBegin);
}
           
  1. setCharAt(int index, char ch)

    清空緩沖區,并将下标為index位置的字元 改成ch

public synchronized void setCharAt(int index, char ch) {
    if ((index < 0) || (index >= count))
        throw new StringIndexOutOfBoundsException(index);
    toStringCache = null;
    value[index] = ch;
}
           

9.append

StringBuffer中的append方法也有很多

  1. append(Object obj)
  2. append(String str)
  3. append(StringBuffer sb)
  4. append(AbstractStringBuilder asb)
  5. append(CharSequence s)
  6. append(CharSequence s, int start, int end)
  7. append(char[] str)
  8. append(char[] str, int offset, int len)
  9. append(boolean b)
  10. append(char c)
  11. append(int i)
  12. appendCodePoint(int codePoint)
  13. append(long lng)
  14. append(float f)
  15. append(double d)

将緩沖區清空,調用父類對應的append方法,然後傳回this

10.删除

​ 1. delete(int start, int end)

​ 将start開始 到end-1位置的字元删除 [start,end)

public synchronized StringBuffer delete(int start, int end) {
    toStringCache = null;
    super.delete(start, end);
    return this;
}
           
  1. deleteCharAt(int index)

    将指定位置的字元删除

public synchronized StringBuffer deleteCharAt(int index) {
    toStringCache = null;
    super.deleteCharAt(index);
    return this;
}
           

11.替換

  1. replace(int start, int end, String str)

    将[star,end)的字元替換成str

public synchronized StringBuffer replace(int start, int end, String str) {
    toStringCache = null;
    super.replace(start, end, str);
    return this;
}
           

12.截取子串

  1. String substring(int start)

    截取從start開始到末尾的字元串

  2. CharSequence subSequence(int start, int end)
  3. String substring(int start, int end)

均調用父類的subString方法

13.插入

  1. StringBuffer insert(int index, char[] str, int offset, int len)

    在字元串index的位置 插入str從offset開始 長度為len的字元串

  2. StringBuffer insert(int offset, Object obj)

    将obj轉為String 插入到offset開始的位置

  3. StringBuffer insert(int offset, String str)
  4. StringBuffer insert(int offset, char[] str)
  5. insert(int dstOffset, CharSequence s)
  6. StringBuffer insert(int dstOffset, CharSequence s, int start, int end)

    同1 差不多

  7. StringBuffer insert(int offset, boolean b)
  8. StringBuffer insert(int offset, char c)
  9. StringBuffer insert(int offset, int i)
  10. StringBuffer insert(int offset, long l)
  11. StringBuffer insert(int offset, float f)
  12. StringBuffer insert(int offset, double d)

14.比對

  1. indexOf(String str) 從第一位開始尋找,比對字元串str的首位下标
  2. int indexOf(String str, int fromIndex) 從fromIndex往後開始尋找 。。。
  3. lastIndexOf(String str) 從最後一位開始尋找,比對字元串str的首位下标
  4. lastIndexOf(String str, int fromIndex) 從fromIndex往前開始尋找

15.toString

public synchronized String toString() {
    if (toStringCache == null) {
        toStringCache = Arrays.copyOfRange(value, 0, count);
    }
    return new String(toStringCache, true);
}
           

若緩沖區不為空,則直接傳回緩沖區的内容,若為空則将value拷貝一份到緩沖區 再傳回。