StringBuilder和StringBuffer详解

本文详细介绍了Java中的StringBuilder类,包括其线程安全与非线程安全的概念,常用构造方法和成员方法。通过实例说明了StringBuilder的自动扩容机制,并分析了其扩容算法。此外,还讨论了StringBuilder与StringBuffer、String之间的转换方法以及效率比较。在笔试考点中,解释了StringBuilder成员方法返回自身对象的原因,以及如何进行相互转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1 基本概念

  • String描述的字符串是个常量,不可改变,会单独申请一块内存空间。在java代码中描述大量类似的字符串时,可能会造成内存空间的浪费
  • 为了解决上述问题,使用可改变的字符串即可:
    • Stringbuffer类 :JDK1.0开始存在,属于线程安全,所以效率低下
    • StringBuilder类 :JDK1.5开始存在,属于非线程安全,所以效率较高
    • 一般开发用StringBuilder

简单举例解释一下 ,线程安全和 非线程安全:

大妈买菜为例!一大堆大妈早上,就围在超市门口等开门,抢折扣的鸡蛋之类的食物。

  • 线程安全

    ​ 大妈们,必须按照超市规定,排队,一个一个买。等结算完金额之后,下一个大妈才能开始购物。要20分钟,才能卖完

    • 对于大妈来说:安全的
    • 对于超市来说:卖东西的效率是低下的
  • 非线程安全

    ​ 大妈们为了抢菜,又挤,又抢,还有人骂了起来,三下五除二,不到2分钟,菜就卖完了。

    • 对于大妈来说:不安全的,可能会发生意外
    • 对于超市来说:东西卖的贼快,效率高

1.2 StringBuilder常用的构造方法

方法声明功能介绍
StringBuilder()无参构造来构建对象,初始容量为16
StringBuilder( int capacity )根据参数指定的容量,来构造对象
StringBuilder( String str )根据字符串,来指定构造对象,容量大小为:16 + 字符串长度

1.3 StringBuilder常用成员方法

方法声明功能介绍
int capacity()返回方法调用对象的容量大小(虚拟大小)
int length()返回字符串中的字符个数(实际大小)
StringBuilder insert( int offset, String str)指定索引插入字符,返回引用(调用该方法)
StringBuilder append( String str )在字符串末尾追加字符串,返回引用
StringBuilder deleteCharAt( int index )删除指定索引的字符,返回引用
StringBuilder delete( int start, int end )从 start索引 开始删除字符,到 end索引-1 处,停止删除
StringBuilder replace( int start, int end, String str )从 start索引 开始,到end索引-1 处的字符串,全部用 str替换掉
StringBuilder reverse()字符串翻转

1.4 StringBuilder的扩容算法的源码解析

举例探讨 StringBuilder的自动扩容机制:

StringBuilder sb = new StringBuilder("01234567");
String str = "qwertyuiop"
sb.append(str);  
  1. 看append方法的源码:

    @Override
        public StringBuilder append(String str) {
            // super,调用了父类的append方法
            super.append(str);
            // 返回this,即返回当前调用该方法的对象
            return this;
        }
    
  2. (append源码内) 进入父类的append方法,查看源码

public AbstractStringBuilder append(String str) {
    // 判断str是否为空
    if (str == null)
        return appendNull();
    
    // 获取当前str的长度
    int len = str.length();
    // ensureCapacityInternal方法,确保容量足够的方法
    // 参数count:即sb引用对象的长度,count= sb.length()
    ensureCapacityInternal(count + len);
    
    
/* ______________  进入ensureCapacityInternal方法 ____________*/

    // minimumCapacity = 扩容前的长度 + 追加字符串的长度
    private void ensureCapacityInternal(int minimumCapacity) {
        
        // char[] value (Stringbuilder本质上就是一个字符数组)
        // value.length:指Stringbuilder扩容前的容量
        // 这个if判断,是用来判断是否扩容,true,则扩容
        if (minimumCapacity - value.length > 0) {
            // Arrays.copyOf: 数组的拷贝,将数组的内容拷贝到一个新的数组中
            // 将 value,即扩容前的数组拷贝到, newCapacity(minimumCapacity)返回的数组中
            // newCapacity(minimumCapacity)返回的是一个,扩容前的容量*2+2的一个容量大小的数组
            value = Arrays.copyOf(
                value,
                newCapacity(minimumCapacity));
        }
    } 

总结:

  • StringBuilder的自动扩容机制为,扩容前的容量 * 2+ 2 = 扩容后的数组容量
  • 要特别注意,容量 != 长度, 容量 = 数组能够拥有的最大长度

在这里插入图片描述

  • 还有就是,如果一次性追加字符串的长度,超过了自动扩容后的容量。那么,会直接让追加后字符串的容量最为扩容后数组的容量

    在这里插入图片描述

  • StringBuilder、StringBuffer作为参数时,会改变本身的值。而String就不会

1.5 常见笔试考点

考点1:StringBuilder类的对象本身会被修改,为什么成员方法还要返回自身对象呢?

为了连续调用,即链式编程

sb.reverse().append("1").insert(0, "X").delete(0, 3);

考点2:实现 StringBuilder 和 String 之间的相互转换

  1. StringBuilder 转 String

    String str = sb.toString();
    
  2. String 转 StringBuilder

    // 构造方法即可
    StringBuilder s =new StringBuilder(str);
    

考点3:String,StringBuilder,StringBuffer三者之间效率比较

效率:StringBuilder > StringBuffer > String

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯子的模样

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值