Java源码分析之StringBuilder,StringBuffer

这两个类极为相似,都是继承自AbstractStringBuilder,并且都实现了Serializable, CharSequence,区别也很明显,StringBuilder不支持多线程,而StringBuffer支持多线程

由于是继承自AbstractStringBuilder,所以不需要成员变量了,StringBuffer中有char[] toStringCache;

将两个类放一起,以便形成对比

构造函数

//两个类的构造方法完全相同,都是调用父类的构造函数,并且留有16的空间
publicStringBuilder() {
    super(16);
}
public StringBuilder(int capacity) {
    super(capacity);
}
public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}
public StringBuilder(CharSequence seq) {
    this(seq.length() + 16);
    append(seq);
}

基本方法

append

//先看StringBuilder
public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

//StringBuffer,CharSequence,char[]与之类似
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

//boolean,char,long,float,double与之类似
public StringBuilder append(int i) {
    super.append(i);
    return this;
}
//StringBuffer
public synchronized StringBuffer append(Object obj) {
    toStringCache = null;
    super.append(String.valueOf(obj));
    return this;
}

//StringBuffer,CharSequence,char[]与之类似
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

//boolean,char,long,float,double与之类似
public synchronized StringBuffer append(int i) {
    toStringCache = null;
    super.append(i);
    return this;
}

可见,两者并没有什么不同,除了StringBuffer有synchronized,对所有的方法都加了synchronized

insert

//StringBuilder
public StringBuilder insert(int index, char[] str, int offset,
                            int len)
{
    super.insert(index, str, offset, len);
    return this;
}

public StringBuilder insert(int offset, Object obj) {
        super.insert(offset, obj);
        return this;
}

public StringBuilder insert(int offset, int i) {
    super.insert(offset, i);
    return this;
}
//StringBuffer
publicsynchronized StringBuffer insert(int index, char[] str, int offset,
                                        int len)
{
    toStringCache = null;
    super.insert(index, str, offset, len);
    return this;
}

public synchronized StringBuffer insert(int offset, Object obj) {
    toStringCache = null;
    super.insert(offset, String.valueOf(obj));
    return this;
}

public StringBuffer insert(int offset, int i) {
    // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
    // after conversion of i to String by super class method
    // Ditto for toStringCache clearing
    super.insert(offset, i);
    return this;
}

两个类也是基本相同,除了synchronized

delete

//StringBuilder
publicStringBuilder delete(int start, int end) {
    super.delete(start, end);
    return this;
}

public StringBuilder deleteCharAt(int index) {
    super.deleteCharAt(index);
    return this;
}

public StringBuilder replace(int start, int end, String str) {
    super.replace(start, end, str);
    return this;
}
//StringBuffer
public synchronized StringBuffer delete(int start, int end) {
    toStringCache = null;
    super.delete(start, end);
    return this;
}

public synchronized StringBuffer deleteCharAt(int index) {
    toStringCache = null;
    super.deleteCharAt(index);
    return this;
}

public synchronized StringBuffer replace(int start, int end, String str) {
    toStringCache = null;
    super.replace(start, end, str);
    return this;
}

reverser

public StringBuilder reverse() {
    super.reverse();
    return this;
}

publicsynchronized StringBuffer reverse() {
    toStringCache = null;
    super.reverse();
    return this;
}

toString

//StringBuilder
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

//StringBuffer
public synchronized String toString() {
    if (toStringCache == null) {
        toStringCache = Arrays.copyOfRange(value, 0, count);
    }
    return new String(toStringCache, true);
}

接下来这些,就是StringBuffer独有的了

//初看还在想,这些为什么还要加synchronized。如果一个方法修改了value,那么同步使用length()方法就会出问题
public synchronized int length() {
    return count;
}

public synchronized int capacity() {
    return value.length;
}

public synchronized void ensureCapacity(int minimumCapacity) {
    if (minimumCapacity > value.length) {
        expandCapacity(minimumCapacity);
    }
}

//同样的道理,这个也加了synchronized
public synchronized char charAt(int index) {
    if ((index < 0) || (index >= count))
        throw new StringIndexOutOfBoundsException(index);
    return value[index];
}

public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
                                  int dstBegin)
{
    super.getChars(srcBegin, srcEnd, dst, dstBegin);
}
public synchronized void setLength(int newLength) {
    toStringCache = null;
    super.setLength(newLength);
}

public synchronized void setCharAt(int index, char ch) {
    if ((index < 0) || (index >= count))
        throw new StringIndexOutOfBoundsException(index);
    toStringCache = null;
    value[index] = ch;
}
public synchronized String substring(int start) {
    return substring(start, count);
}

public synchronized String substring(int start, int end) {
    return super.substring(start, end);
}

publicsynchronized CharSequence subSequence(int start, int end) {
    return super.substring(start, end);
}

从这些源码也可以看出,StringBuilder与StringBuffer没什么不同,在使用中,如果是单线程,尽量使用StringBuilder,相比StringBuffer稍快点一点儿,而如果是多线程,那就只能使用StringBuffer了

你可能感兴趣的:(Java)