美文网首页
StringBuilder和StringBuffer

StringBuilder和StringBuffer

作者: 0x70e8 | 来源:发表于2018-03-25 11:59 被阅读0次

    StringBuilder和StringBuffer

    StringBuilder和StringBuffer都是抽象类AbstractStringBuilder的实现类,抽象类ASB实现了大部分的核心功能,最主要的append方法,是在ASB中写好的,子类中append基本都是调用此方法。
    StringBuffer和StringBuilder的功能基本一致,可以说StringBuffer是StringBuilder的同步版本。

    看一下ASB。

    AbstractStringBuilder

    定义和基本属性

    实际上StringBuilder,是String类的可变版本,它低层也是char数组,像ArrayList类一样动态扩容,只是这个数组没有被限制修改,也没有final限定符,String类的“修改”是指向新的字符串,StringBuilder的修改就是直接修改低层char数组。

    abstract class AbstractStringBuilder implements Appendable, CharSequence {
        /**
         * The value is used for character storage.
         */
        char[] value;
    
        /**
         * The count is the number of characters used.
         */
        int count;
    
        /**
         * This no-arg constructor is necessary for serialization of subclasses.
         */
        AbstractStringBuilder() {
        }
    
        /**
         * Creates an AbstractStringBuilder of the specified capacity.
         */
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
        // ...
    }
    
    Append方法
    1. append怎么实现的
      看下SB的核心使用方法append,ASB一共重载了14个append方法,最核心的差不多是这个:
        public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            // 检查char数组是否需要扩容
            ensureCapacityInternal(count + len);
            //  使用了String类的char数组拷贝,把要追加的str copy到value的后面(以count为beginIndex)
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }
    

    所以append的实现就是把新的字符串的char数组的元素,放到原来数组里面。这个放置动作,是借助System.arraycopy方法。
    看下ASB是如何动态扩容的:

        /**
         * This implements the expansion semantics of ensureCapacity with no
         * size check or synchronization.
         */
        void expandCapacity(int minimumCapacity) {
            int newCapacity = value.length * 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);
        }
    

    可以看到最后一句,把value指向新的数组,(这也是为什么value变量没有使用final的原因)。
    对于String类来说,String的value是final的,String类的char数组不能动态扩容。一次初始化的字符串就是贯穿它的生命周期的长度,往后的“修改”都是创建的新的String对象返回的。String类对象不可变是因为内部char数组没有开放修改一定要牢记心中。
    ArrayList(基于对象数组)的动态扩容,也是使用的数组copy(Arrays.copyOf)。

    1. append null
      ASB是支持append null的,而且它的处理方法是直接追加{'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;
        }
    
    insert方法

    insert方法低层实现是对数组的copy操作。

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

    StringBuilder和StringBuffer

    StringBuffer和StringBuilder,实现了ASB,前者线程安全,后者不是。
    二者在实现时基本是调用super方法,核心都在ASB里面了。

    相关文章

      网友评论

          本文标题:StringBuilder和StringBuffer

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