JAVA StringBuilder&StringBuffer学习

StringBuilder&StringBuffer

本文源码基于JDK8

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

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value; //字符数组
    int count;
}
  • Serializable:可以序列化的标志;
  • CharSequence接口:包含了charAt()、length() 、subSequence()、toString()这几个方法,String类也实现了这个接口;
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;
}

总结

  • StringBuilder和StringBuffer都是可变字符串,前者线程不安全,后者线程安全。

  • StringBuilder和StringBuffer的大部分方法均调用父类AbstractStringBuilder的实现。其扩容机制首先是把容量变为原来容量的2倍加2。最大容量是Integer.MAX_VALUE,也就是0x7fffffff。

  • StringBuilder和StringBuffer的默认容量都是16,最好预先估计好字符串的大小避免扩容带来的时间消耗

public StringBuilder() {
    super(16);
}
public StringBuffer() {
    super(16);
}
  • StringBuilder是jdk1.5引进的,而StringBuffer在1.0就有了;

猜你喜欢

转载自blog.csdn.net/luoyoub/article/details/80193181
今日推荐