美文网首页
JAVA StringBuilder&StringBuffer学

JAVA StringBuilder&StringBuffer学

作者: luoyoub | 来源:发表于2018-05-04 12:02 被阅读0次

    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就有了;

    相关文章

      网友评论

          本文标题:JAVA StringBuilder&StringBuffer学

          本文链接:https://www.haomeiwen.com/subject/apldrftx.html