JDK源码解析---StringBuffer

1.概述

​ StringBuffer,由名字可以看出,是一个String的缓冲区,也就是说一个类似于String的字符串缓冲区,和String不同的是,它可以被修改,而且是线程安全的。但是多个线程同时操作StringBuffer时候,对它而言只有一个线程在进行操作是串行执行的。StringBuffer在任意时刻都有一个特定的字符串序列,不过这个序列和它的长度可以通过一些函数调用进行修改。StringBuffer会自动增加容量

​ 所有的修改操作(增加,删除,替换)均会造成缓冲区清空,修改操作均是synchronized修饰

2.类图

在这里插入图片描述

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拷贝一份到缓冲区 再返回。

猜你喜欢

转载自blog.csdn.net/gongsenlin341/article/details/107483112