String、StringBuilder和StringBuffer

一、三者区别

String每次增加数据都会开辟新空间,存储数据,然后将之前的那一块空间通过GC进行回收

StringBuilder是可变长度的,数据增加是直接在现有的空间中进行操作。但是它不是线程安全的。

StringBuffer也是可变长度的,数据增加也是直接在现有的空间中进行操作。但是它是线程安全的。

(StringBuilder和StringBuffer每次都会多开辟一些空间,避免每次往字符串后面添加字符时都要开辟空间,新建对象。只有当开辟的空间已经不够用时,才会重新开辟一个新空间。有点像是以空间换时间。String和StringBuilder的区别很像定长数组和动态数组的区别。)

二、源码分析

1、StringBuffer

1.1、构造方法一——用户可自己指定StringBuilder的初始大小。

根据实际情况来指定大小的话可以减少开辟空间的次数,也可以减少空间的浪费

/**
 * Constructs a string buffer with no characters in it and
 * the specified initial capacity.
 *
 * @param      capacity  the initial capacity.
 * @exception  NegativeArraySizeException  if the {@code capacity}
 *               argument is less than {@code 0}.
 */
/*
 * 构造一个没有字符的空字符串,大小为capacity。
 * 如果capacity小于0会返回一个异常.
 */
public StringBuffer(int capacity) {
    super(capacity);
}

1.2、构造方法二——默认大小的构造方法(输入的字符串长度+16)


    /**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * {@code 16} plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

1.3、普通方法——synchronized(线程安全的)

    @Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }


    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
    }

1.4、容量扩展方法

/**
 * This implements the expansion semantics of ensureCapacity with no
 * size check or synchronization.
 */
/*
 * 当原有容量不够时,对其进行扩展(乘以2再加上2)
 * 
 */
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);
}

2.StringBuilder除了普通方法没有加synchronized关键字,其他都和StringBuffer差不多。

三、使用场景

String针对的是少量字符串的操作。

当字符串较多,并且是多线程时,应当用StringBuffer。

当字符串较多,并且是单线程时,应当用StringBuilder。

四、运行速度

StringBuilder>StringBuffer>String

猜你喜欢

转载自blog.csdn.net/Alexwym/article/details/82047918
今日推荐