java.lang中StringBuilder源码分析

类定义

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence

StringBuilder 类被声明为 final,说明它不能再被继承。同时它继承了 AbstractStringBuilder 类,并实现了 Serializable 和 CharSequence 两个接口。

 

构造方法
有若干种构造方法,可以指定容量大小参数,如果没有指定则构造方法默认创建容量为16的字符串对象。如果 COMPACT_STRINGS 为 true,即使用紧凑布局则使用 LATIN1 编码(ISO-8859-1编码),则开辟长度为16的 byte 数组。而如果是 UTF16 编码则开辟长度为32的 byte 数组。

public StringBuilder() {
        super(16);
    }

AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }

public StringBuilder(int capacity) {
        super(capacity);
    }



如果构造函数传入的参数为 String 类型,则会开辟长度为str.length() + 16的 byte 数组,并通过append方法将字符串对象添加到 byte 数组中。

public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }



类似地,传入参数为 CharSequence 类型时也做相同处理。

public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

主要方法
append方法

 

如果传入 String 类型参数则调用父类的append方法将字符串对象添加到 StringBuilder 的 byte 数组中,然后返回 this。append 的逻辑为: 
* String 对象为 null的话则在 StringBuilder 的 byte 数组中添加n u l l四个字符。 
* 通过ensureCapacityInternal方法确保有足够的空间,如果没有则需要重新开辟空间。 
* 通过putStringAt方法将字符串对象里面的 byte 数组复制到 StringBuilder 的 byte 数组中,使用了System.arraycopy进行复制。 
* count 为已使用的字符数,将其加上复制的字符串长度。 
* 返回 this。

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

public AbstractStringBuilder append(String str) {
        if (str == null) {
            return appendNull();
        }
        int len = str.length();
        ensureCapacityInternal(count + len);
        putStringAt(count, str);
        count += len;
        return this;
    }

首先获取现有的容量大小。 
* 如果需要的容量大于现有容量,则需要扩充容量,并且将原来的数组复制过来。 
newCapacity方法用于确定新容量大小,将现有容量大小扩大一倍再加上2,如果还是不够大则直接等于需要的容量大小。

delete方法


该方法用于将指定范围的字符删掉,逻辑为: 
* end 不能大于已使用字符数 count,大于的话则令其等于 count。 
* 通过checkRangeSIOOBE检查范围合法性。 
* 通过shift方法实现删除操作,其通过System.arraycopy来实现,即把 end 后面的字符串复制到 start 位置,即相当于将中间的字符删掉。 
* 修改已使用字符数 count 值。 
* 返回 this。

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

public AbstractStringBuilder delete(int start, int end) {
        int count = this.count;
        if (end > count) {
            end = count;
        }
        checkRangeSIOOBE(start, end, count);
        int len = end - start;
        if (len > 0) {
            shift(end, -len);
            this.count = count - len;
        }
        return this;
    }

private void shift(int offset, int n) {
        System.arraycopy(value, offset << coder,
                         value, (offset + n) << coder, (count - offset) << coder);
    }

总结:stringbuilder 效率高,线程不安全,长度可变,初始长度16,当调用有参构造方法时长度为参数长度+16,当调用append方法时会先判断需要容量是否大于现有容量,如果大于则扩容一倍+2,如果还大于,则直接等于需要容量。

更多详细内容见https://blog.csdn.net/wangyangzhizhou/article/details/80446222

你可能感兴趣的:(java.lang中StringBuilder源码分析)