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源码

java 复制代码
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源码

java 复制代码
 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源码

java 复制代码
 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。

相关推荐
爱吃生蚝的于勒43 分钟前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田2 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
魔道不误砍柴功4 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
枫叶_v4 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
wclass-zhengge4 小时前
SpringCloud篇(配置中心 - Nacos)
java·spring·spring cloud
路在脚下@4 小时前
Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点和适用场景
java·spring boot·servlet