自学内容网 自学内容网

StringBuilder和StringBuffer

目录

(一)为什么要引入StringBuilder和StringBuffer

(二)StringBuilder和StringBuffer

(1)底层数组长度

(2)StringBuilder与StringBuffer扩容机制

(3)StringBuilder和StringBuffer区别

 (三)总结


(一)为什么要引入StringBuilder和StringBuffer

上一个文章我们已经了解了String类——>String类

String的不可变性意味着一旦创建了String对象,就不能更改其内容。如果需要修改字符串,就必须创建一个新的String对象。这种特性在需要频繁修改字符串的场景下会导致大量的临时对象被创建,可能会导致更高的内存使用,从而增加垃圾回收的负担,并可能影响性能.

而StringBuilder和StringBuffer底层维护的是一个可变的数组,当遇到需要频繁修改字符串的场景下能够大量减少临时对象的创建,提升性能。

(二)StringBuilder和StringBuffer

(1)底层数组长度

StringBuilder和StringBuffer的底层数组默认长度是16

如下图为StringBuilder源码中,若创建StringBuilder时没传入参数,那么会默认创建一个大小为16的数组

若传入了参数,创建数组的大小=当前参数值的长+16

 如下图为StringBuilder源码中,若创建StringBuilder时传入参数,那么会默认创建一个大小为当前参数值长(str.length())+ 16的数组

(2)StringBuilder与StringBuffer扩容机制

2.1在append方法内部,会调用ensureCapacityInternal方法,该方法会检查当前容量是否足够。

append源码

public AbstractStringBuilder append(char[] str) {
        int len = str.length;
        ensureCapacityInternal(count + len);//调用此方法判断数组是否需要扩容
        System.arraycopy(str, 0, value, count, len);
        count += len;
        return this;
    }

2.2 如果当前容量不足以存储新的字符(即最小所需容量大于当前容量),则需要扩容

ensureCapacityInternal源码

 private void ensureCapacityInternal(int minimumCapacity) {//所需最小数组大小
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {如果所需最小数组大于当前数组
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));//调用newCapacity方法扩容并将原数组copy到新数组
        }
    }

2.3 调用newCapacity方法计算新的容量。新的容量是当前容量的两倍加2(即2n+2,其中n是当前容量),如果计算出的新容量仍然小于最小所需容量,则将新容量设置为最小所需容量

newCapacity源码

 private int newCapacity(int minCapacity) {//传入所需最小数组大小
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;//将当前数组×2+2
        if (newCapacity - minCapacity < 0) {//如果扩容过后还小于所需最小数组大小
            newCapacity = minCapacity;//直接等于所需最小数组大小
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

(3)StringBuilder和StringBuffer区别

StringBuilder线程不安全。StringBuilder 的方法没有被 synchronized 修饰,因此它不能同步访问,多个线程同时操作同一个 StringBuilder 实例可能会导致数据不一致的问题,但效率有所提升。

StringBuffer线程安全。StringBuffer 的所有公开方法都被 synchronized 修饰,这意味着在多线程环境中,对 StringBuffer 的操作是同步的,从而保证了线程安全,但也牺牲了效率

 (三)总结

1.String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

2.StringBuffer与StringBuilder大部分功能是相似的

3.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作,因此在多线程环境下使用StringBuffer,在单线程环境下为提升效率,可以使用StringBuilder。


原文地址:https://blog.csdn.net/m0_73233932/article/details/140588320

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!