StringBuffer与StringBuilder的区别

目录

前言:

StringBuffer与StringBuilder的共同之处:

StringBuffer与StringBuilder的不同之处:

使用方法(以StringBuffer为例):

如何优化StringBuffer的性能?

String为什么是不可变的?

StringBuilder/StringBuffer为什么是可变的呢?

参考文献:


前言:

思考:我们在实际的开发中,如果需要进行字符串的频繁拼接,会有什么问题?

因为java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存。造成内存空间的浪费,给java的方法区字符串常量池带来很大的压力。

    String s = "abc";
    s += "hello";

就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象。

所以如果以后需要进行大量字符串的拼接操作,建议使用JDK中自带的:

        java.lang.StringBuffer

        java.lang.StringBuilder

StringBuffer与StringBuilder的共同之处:

1、都继成了AbstractStringBuilder这个抽象类,实现了CharSequence接口

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
 
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

2、其append方法都是 super.append(str),调用了父类AbstractStringBuilder的append(String str)方法

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
 
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

3、初始容量都是16和扩容机制都是"旧容量*2+2"。 

4、底层都是用char[]字符数组实现,且字符数组都是可变的,这点不同于String

StringBuffer与StringBuilder的不同之处:

1、StringBuffer中的方法都有synchronized关键字修饰。表示StringBuffer在多线程环境下运行是安全的。StringBuilder中的方法都没有synchronized关键字修饰,表示StringBuilder在多线程环境下运行是不安全的。

        即:StringBuffer是线程安全的。StringBuilder是非线程安全的。

2、StringBuffer从JDK1.0就有了,StringBuilder是JDK5.0才出现

3、StringBuffer比StringBuilder多了一个toStringCache字段,用来在toString方法中进行缓存,每次append操作之前都先把toStringCache设置为null,若多次连续调用toString方法,可避免每次Arrays.copyOfRange(value, 0, count)操作,节省性能。

使用方法(以StringBuffer为例):

        StringBuffer stringBuffer = new StringBuffer();

// 默认创建一个初始化容量为16个char[] 数组。(字符串缓冲区对象)

// 调用 append()方法对字符串进行拼接操作。

        stringBuffer.append("a");
        stringBuffer.append(3.14);
        stringBuffer.append(true);

// append方法底层在进行追加的时候,如果byte数组满了,会自动扩容(复制进一个新的数组,删掉原来的数组)。

如何优化StringBuffer的性能?

        在创建StringBuffer的时候尽可能给定一个初始化容量。最好减少底层数组的扩容次数。预估计一下,给一个大一些初始化容量。

如:

        StringBuffer sb = new StringBuffer(100);

String为什么是不可变的?

        String类中有一个byte[]数组,这个byte[]数组采用了final修饰,因为数组一旦创建长度不可变。并且被final修饰的引用一旦指向某个对象之后,不可再指向其它对象,所以String是不可变的!

StringBuilder/StringBuffer为什么是可变的呢?

        StringBuffer/StringBuilder内部实际上也是一个byte[]数组,但这个byte[]数组没有被final修饰。StringBuffer/StringBuilder的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法。所以StringBuilder/StringBuffer适合于使用字符串的频繁拼接操作。

参考文献:

彻底弄懂StringBuffer与StringBuilder的区别_Relian哈哈的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秦矜

对你有帮助的话,请我吃颗糖吧~

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

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

打赏作者

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

抵扣说明:

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

余额充值