AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大的帮助。
先来看看该类的声明:
abstract class AbstractStringBuilder implements Appendable, CharSequence {}
该类实现Appendable和CharSequence接口。
成员变量:
char[] value;//字符数组用来存储字符串 int count;//值是字符串数组被使用的长度。注意,字符数组被使用长度不等于字符数组长度
构造器:
AbstractStringBuilder() {//无参构造器 } AbstractStringBuilder(int capacity) {//带一个int参数构造器,capacity是字符串数组的大小,相当于字符串容器的大小 value = new char[capacity]; }
方法:
//返回字符串实际大小
public int length() { return count; }
//返回容器容量 public int capacity() { return value.length; }
//确保容器的大小比minimumCapcipty大 public void ensureCapacity(int minimumCapacity) { if (minimumCapacity > 0) ensureCapacityInternal(minimumCapacity); } private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0)//如果minimumCapacity比容器大 expandCapacity(minimumCapacity);//扩容 } void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2;//新容量是(原容量大小+1)*2 if (newCapacity - minimumCapacity < 0)//如果扩容后仍然不够minimumCapacity newCapacity = minimumCapacity;//那么新容量就是minimumCapacity if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity);//创建新容器 }
//这个方法是让容器的大小变成跟字符串大小一样 public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } }
//设置字符串的长度,如果比原来长,多出来的部分填充'\0',如果比原来短,截断 public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); ensureCapacityInternal(newLength); if (count < newLength) { Arrays.fill(value, count, newLength, '\0'); } count = newLength; }
//返回index位置的字符 public char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; }
//注意下面的append方法,重载的方法很多,支持各种类型参数的append,仅列出部分
//在字符串末尾添加一个字符串,该字符串由obj的toString方法决定 public AbstractStringBuilder append(Object obj) { return append(String.valueOf(obj)); }
//在字符串末尾添加一个字符串str public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
//在字符串后面添加null字符串 private AbstractStringBuilder appendNull() { int c = count; ensureCapacityInternal(c + 4); final char[] value = this.value; value[c++] = 'n'; value[c++] = 'u'; value[c++] = 'l'; value[c++] = 'l'; count = c; return this; }
//删除start至end的字符子串,容量不变,字符串长度减少end-start public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end); count -= len; } }
//返回start至end的子串 public String substring(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) throw new StringIndexOutOfBoundsException(end); if (start > end) throw new StringIndexOutOfBoundsException(end - start);
return new String(value, start, end - start); }
//在index位置插入str从offset开始,长度为len的子串 public AbstractStringBuilder insert(int index, char[] str, int offset, int len) { if ((index < 0) || (index > length())) throw new StringIndexOutOfBoundsException(index); if ((offset < 0) || (len < 0) || (offset > str.length - len)) throw new StringIndexOutOfBoundsException( "offset " + offset + ", len " + len + ", str.length " + str.length); ensureCapacityInternal(count + len); System.arraycopy(value, index, value, index + len, count - index); System.arraycopy(str, offset, value, index, len); count += len; }
//将字符串的顺序颠倒,如"abc" reverse 成 "cba" public AbstractStringBuilder reverse() { boolean hasSurrogates = false; int n = count - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this; }
//...还有其他的方法
可以看到AbstractStringBuilder几乎定义了所有字符串的操作,同时它接受任意类型的拼接,在一个动态数组上操作字符串,对于频繁的字符操作,相比于直接使用String来操作new一个新的String,能提高效率。