JAVA StringBuilder&StringBuffer学

2018-05-04  本文已影响0人  luoyoub

StringBuilder&StringBuffer

本文源码基于JDK8

StringBuilder与StringBuffer是两个常用的操作字符串的类。StringBuilder是线程不安全的,而StringBuffer是线程安全的;StringBuilder、StringBuffer都继承自AbstractStringBuilder

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value; //字符数组
    int count;
}
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{}
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{}

append方法比较

AbstractStringBuilder抽象类的append方法

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);//确保不会溢出,必要是扩容
    str.getChars(0, len, value, count);//将整个str拷贝到value的末尾
    count += len;            //增加计数
    return this;
}

private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0)  //如果会溢出,则扩容
        expandCapacity(minimumCapacity);
}

void expandCapacity(int minimumCapacity) {
    int newCapacity = value.length * 2 + 2;   //新的容量是原容量的2倍+2
    if (newCapacity - minimumCapacity < 0)
        newCapacity = minimumCapacity;
    if (newCapacity < 0) {
        if (minimumCapacity < 0) // overflow
            throw new OutOfMemoryError();
        newCapacity = Integer.MAX_VALUE;
    }
    value = Arrays.copyOf(value, newCapacity);  
}

注意:如果str是null,则会调用appendNull()方法。这个方法其实是追加了'n'、'u'、'l'、'l'这几个字符

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

StringBuffer

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

toStringCache这个变量是用于最近一次toString()方法的缓存,任何时候只要StringBuffer被修改了这个变量会被赋值为null;

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

StringBuilder

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

总结

public StringBuilder() {
    super(16);
}
public StringBuffer() {
    super(16);
}
上一篇下一篇

猜你喜欢

热点阅读