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*2int 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';
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);
?
?
好了,就看到这吧。
?
?