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 的操作是同步的,从而保证了线程安全,但也牺牲了效率

(4)StringBuilder和StringBuffer常用方法

绿色为返回值类型,StringBuffer返回类型可替换为StringBuilder类型

StringBuff append(String str) :在尾部追加,相当于String += ,可以追加: boolean char char[], double、 float int long Object String StringBuff 的变量
char charAt(int index) :获取index 位置的字符
int length():获取字符串的长度
int capacity():获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity) :扩容
void setCharAt(int index, char ch) :将index 位置的字符设置为 ch
int indexOf(String str) :返回str 第一次出现的位置
int indexOf(String str, int fromIndex):从fromIndex 位置开始查找 str 第一次出现的位置
int lastIndexOf(String str):返回最后一次出现str 的位置
int lastIndexOf(String str, int fromIndex) :从fromIndex 位置开始找 str 最后一次出现的位置
StringBuff insert(int offset, String str) :在offset 位置插入:八种基类类型 & String 类型 & Object 类型数据
StringBuffe r deleteCharAt(int index) :删除index 位置字符
StringBuffer delete(int start, int end) :删除[start, end) 区间内的字符
StringBuffer replace(int start, int end, String str) :将[start, end) 位置的字符替换为 str
String substring(int start) :从start 开始一直到末尾的字符以 String 的方式返回
String substring(int start, int end):将[start, end) 范围内的字符以 String 的方式返回
StringBuffer reverse() :反转字符串
String toString() :将所有字符按照String 的方式返回

 (三)总结

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

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

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

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值