欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

StringBuffer源码理解

程序员文章站 2022-04-30 15:15:30
...

StringBuffer 存储和操作字符串

它所继承实现的类和接口

public final class StringBuffer   	extends AbstractStringBuilder   implements java.io.Serializable, CharSequence
 

一.构造函数

1.public StringBuffer( )

构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。

StringBuffer.class

public StringBuffer() {
	super(16);
}

  AbstractStringBuilder.class

char value[];//存内容的字符数组





,StringBuffer中未定义新的变量,一直在操作父类定义的变量
AbstractStringBuilder(int capacity) {
        value = new char[capacity];//在这个例子中是16
}

2.public StringBuffer(int capacity)

构造一个不带字符,但具有指定初始容量的字符串缓冲区。

3.public StringBuffer(String str)

构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。该字符串的初始容量为 16 加上字符串参数的长度。

 StringBuffer.class

 public StringBuffer(String str) {
        //这个执行父类的带参构造函数AbstractStringBuilder(int capacity) 
        super(str.length() + 16);
	append(str);
}
public synchronized StringBuffer append(String str) {
        //执行父类的append(str)
        super.append(str);
        return this;
}

  AbstractStringBuilder.class

public AbstractStringBuilder append(String str) {
	if (str == null) str = "null";
        int len = str.length();
	if (len == 0) return this;
        //新的字符长度
	int newCount = count + len;
	if (newCount > value.length)
            //如果新的字符长度比字符数组分配的空间大,扩大容量
	    expandCapacity(newCount);
	//将字符从此字符串复制到目标字符数组。
	str.getChars(0, len, value, count);
	count = newCount;
	return this;
}       
char value[];//存内容的字符数组






 //扩张容量






void expandCapacity(int minimumCapacity) {
        //newCapacity 新容量,默认+1*2
	int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            //数字超过了Integer的最大值
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
            //默认扩大的容量还是不足存新的字符
	    newCapacity = minimumCapacity;
	}
        //将旧的值剪切到新的字符数组。
        value = Arrays.copyOf(value, newCapacity);
    }

二.append函数

append的步骤类似,

append(String str)

1.先判断是否为null,null就将str="null".

2.再判断str的长度是否为0,为0直接返回。

3.判断value[]字符数组的剩余空间够不够。

4.不够的话new一个char[] 空间为(原来+1)*2,并且判断时候超出Integer的最大值。然后System.arraycopy,将旧的字符数组复制到新的数组中

5.str.getChars,将str写入value[] 中。调用的也是System.arraycopy

append(Object obj)

先执行String.valueOf(obj),然后执行append(str)

append(StringBuffer sb)

第五步不同,调用StringBuffer的getChars方法,内部一样为System.arraycopy.

append(char c[])

1.直接相加计算新的字符长度,

2.长度不够扩张

3.System.arraycopy复制

append(CharSequence s)

1.判断s对象是String 或者StringBuffer的子类,分别调用append(str)或者append(sb)

2.如果不是,则利用value[count++] = s.charAt(i);

append(boolean b)

value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';

append(int i)

 int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1 : stringSizeOfInt(i);//计算i的长度
 
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,99999999, 999999999, Integer.MAX_VALUE };
static int stringSizeOfInt(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
}

 上面的代码计算出数字i的长度

然后利用Integer.getChars将i复制进value[]中,这个方法也很特别,以后再看。

append(long l)

 

  int appendedLength = (l < 0) ? stringSizeOfLong(-l) + 1 : stringSizeOfLong(l);
 
  static int stringSizeOfLong(long x) {
        long p = 10;
        for (int i=1; i<19; i++) {
            if (x < p)
                return i;
            p = 10*p;
        }
        return 19;
    }

 这个是计算long的长度的方法,利用Long.getChars将内容复制入新字符数组中

 

三.其它

删除   StringBuffer delete(int start, int end)

移除此序列的子字符串中的字符。系统直接将后面的字符用 System.arrayCopy复制面搜索的部分大删除起始点。删除掉了start ,end未删除。

删除一个 deleteCharAt(int index)

直接删除一个字符,相当于delete(index,index+1)

替换 replace(int start, int end, String str)

先看容量够不够,end后的内容利用System.arraCopy空出str的长度,然后将str复制进字符数组、

toString()

执行return new String(value, 0, count);

 

 

好了,就看到这吧。