Java基础篇——StringBuilder类和StringBuffer类

和String类型一样,StringBuilder类、StringBuffer类也是用来操作字符串的类。

继承关系图:

 和String类不一样,使用 StringBuilder类或 StringBuffer 类时,每次都会对对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuilder类或StringBuffer 类。

StringBuilder 类在 Jdk5 中被提出,它和 StringBuffer(据说最早的jdk版本中就有这个类) 之间的最大不同在于 StringBuilder 的方法不是线程安全的,但是速度比 StringBuffer 快。

StringBuilder类

StringBuilder类部分源码 

AbstractStrigBuilder类构造方法 

和String类一样,StringBuilder类也不可以被继承、因为类的定义用了final修饰。

StringBuilder对象实质上是一个字符数组,创建 StringBuilder对象不可以直接使用字符串常量,需要new一个对象,使用构造方法创建。使用空参构造方法创建对象时,新建一个长度为16的空字符数组。使用传入参数值为整数的构造方法创建对象时,新建一个长度为参数值的空字符数组。使用传入参数值为字符串对象的构造方法创建对象时,新建一个长度为字符串长度+16的字符数组,并将字符串对象的值复制到字符数组中。

StringBuilder对象保存的是字符数组的引用地址。

public class TestMain {

    public static void main(String[] args) {

        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder(20);
        StringBuilder sb3 = new StringBuilder("abc");

        System.out.println(sb1.length());   //返回对象字符串长度 0
        System.out.println(sb2.length());   //返回对象字符串长度 0
        System.out.println(sb3.length());   //返回对象字符串长度 3
        System.out.println(sb1.capacity()); //返回字符数组长度 16
        System.out.println(sb2.capacity()); //返回字符数组长度 20
        System.out.println(sb3.capacity()); //返回字符数组长度 19
        
    }
}

执行结果:

length和capacity方法源码

count是 StrigBuilder类的父类AbstractStrigBuilder类的成员变量,没有初始化,是个int类型,所以默认值是0,用来保存 StrigBuilder对象实际保存的字符个数(从append方法中可以看出来)。所有length方法返回的是StrigBuilder对象实际保存的字符个数。

capacity方法的返回值是value这个字符数组的长度,不管数组中有没有存满字符,所有capacity方法返回的值也是StrigBuilder对象最大保存的字符个数。

append方法是最常用的方法,使用来拼接字符串的,直接把新的字符串放到原字符串的末尾,组成一个新的字符串,但是不创建新的StrigBuilder对象,新字符串还保存在StrigBuilder对象中。

public class TestMain {

    public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();
        System.out.println(sb);            //空串
        System.out.println(sb.length());   //返回对象字符串长度 0
        System.out.println(sb.capacity()); //返回字符数组长度 16

        sb.append("abcderghijklmnop");
        System.out.println(sb);            //abcderghijklmnop
        System.out.println(sb.length());   //返回对象字符串长度 16
        System.out.println(sb.capacity()); //返回字符数组长度 16

        sb.append("qrst");
        System.out.println(sb);            //abcderghijklmnopqrst
        System.out.println(sb.length());   //返回对象字符串长度 20
        System.out.println(sb.capacity()); //返回字符数组长度 34

        sb.append("abcderghijklmnoprst");
        System.out.println(sb);            //abcderghijklmnopqrstabcderghijklmnoprst
        System.out.println(sb.length());   //返回对象字符串长度 39
        System.out.println(sb.capacity()); //返回字符数组长度 70

    }
}

执行结果:

可以看出,随着调用append方法不断的添加字符串,StringBuilder对象的实际保存字符长度和最大保存字符长度都在变大,实际保存字符长度变大不难理解,那么最大保存字符长度增加(扩容)的原理是什么呢?

查看append方法源代码 

当传入 append方法的参数是非空字符串时,调用ensureCapacityInternal(count + len)方法,传入原字符串长度和新字符串长度之和,查看ensureCapacityInternal方法源码

可以看出是 newCapacity方法改变的最大保存字符长度值,即value.length的值。

 value.length << 1 ,字符数组长度是个int类型数据,在计算机中是用二进制存储的,共四个字节,范围是[-2^{31} ,{2^{31} - 1}],“<<"是左移运算符,value.length << 1,表示length左移一位,因为是二进制存储,所以相当于放大2倍。int newCapacity = (value.length << 1) + 2 的意思是新数组长度是原数组长度的2倍加2

​​​​​​​可以看出,扩容也是需要代价的,所以对于那些不断增加的字符串对象,使用 StringBuilder(int capacity)   构造方法创建对象,并指定合理的初始化大小,减少扩容次数。

StringBuffer类的功能与 Stringbuilder类类似,只不过 StringBuffer类是线程安全的,成员方法都被synchronized修饰。

参考资料:

https://www.runoob.com/java/java-stringbuffer.html

https://blog.csdn.net/qq_44713454/article/details/109090381

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值