java成长笔记

StringBuilder和StringBuffer

2019-08-14  本文已影响0人  G_uest

区别

StringBuffer:jdk 1.0出现,线程安全,效率低

StringBuilder: jdk 1.5出现,线程不安全,效率高

StringBuilder怎么实现的线程安全

StringBuilder 中的大量方法都使用 synchronized 修饰,来实现线程安全,就是因为这样速度才会慢。
二者的实现几乎没什么区别,具有相同的父类和接口,具体实现方法都由父类完成。

StringBuffer 部分源码

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    // toString返回的最后一个值的缓存。每当修改StringBuffer时清除。
    private transient char[] toStringCache;

    // 默认初始化容量为16个字符
    public StringBuffer() {
        super(16);
    }
    
    // 如果构造方法中传入了一个字符串,长度为字符串长度加16
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
    
    // 被 synchronized 修饰方法还有很多,不再一一列举
    @Override
    public synchronized StringBuffer append(String str) {
        // StringBuffer将会被修改,清除 toStringCache
        toStringCache = null;
        super.append(str);
        return this;
    }
    
    // 重写toString方法
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
}


StringBuilder 部分源码

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    // 默认初始化容量为16个字符
    public StringBuilder() {
        super(16);
    }
    
    // 如果构造方法中传入了一个字符串,长度为字符串长度加16
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
    
    // 添加字符串方法
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    
    // toString 方法
    @Override
    public String toString() {
        // 创建一个副本,不要共享数组
        return new String(value, 0, count);
    }
}

扩容方法

先扩充为 原长度 * 2 + 2 的长度,然后判断扩充后的长度是否大于StringBuilder拼接字符串后的长度(新添加的+已有的长度),如果小于的话,就执行newCapacity = StringBuilder(StringBuilder为拼接后字符串的长度)。如果newCapacity<0说明数组长度已经超出了范围,这时调用hugeCapacity方法,执行newCapacity = Integer.MAX_VALUE
AbstractStringBuilder 部分源码

// 用于字符存储。
char[] value;

// 数组最大长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

// 扩容方法
private int newCapacity(int minCapacity) {
    // 先扩充为 原长度 * 2 + 2 的长度
    int newCapacity = (value.length << 1) + 2;
    // 判断扩充后的长度是否大于StringBuilder拼接字符串后的长度
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
        ? hugeCapacity(minCapacity)
        : newCapacity;
}

// 数组再次扩容,但是长度不能超出int范围
private int hugeCapacity(int minCapacity) {
    if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
        throw new OutOfMemoryError();
    }
    return (minCapacity > MAX_ARRAY_SIZE)
        ? minCapacity : MAX_ARRAY_SIZE;
}
上一篇下一篇

猜你喜欢

热点阅读