StringBuffer源码理解

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);

 

 

好了,就看到这吧。

 

 

你可能感兴趣的:(StringBuffer)