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);
好了,就看到这吧。