java - StringBuffer 和 StringBuilder 介绍和使用

StringBuffer  和  StringBuilder

 我们之前说过,字符串是不可变的,那么如果我们使用 加号 来进行拼接,那么会在字符串常量池中创建一些我们需要字符串常量,然后在进行拼接,并不是在原来的字符串基础之上进行修改。

String对象一旦被声明就不能被改变,如果进行改变,改变的是对象的应用而已。

而所谓的StringBuffer  和  StringBuilder,其实就是两个类,目的就是为了字符串的修改方便。

StringBuffer 和 StringBuilder 大部分功能是相同的,我们先来主要了解一下StringBuilder。

如果我们使用 加号 来进行拼接,如下例子:

    public static void main(String[] args) {
        String str = "hello";
        String str1 = "world";
        
        str = str + str1;
    }

 我们来查看这个代码的反汇编:

 如上图,在使用 + 拼接之前,编译器先创建了 StringBuilder 对象。

 然后再使用了 两次 append()方法来进行拼接。

那么如果我们使用 “ + ” 来进行字符串的拼接,那么java编译器会StringBuilder中的append() 拼接。

 那么为什么此处要调用两次append()呢?

其实上述使用 加号 的拼接字符串代码,写成 使用 StringBuilder 来拼接的话,应该是以下写法:

    public static void main15(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("hello");
        stringBuilder.append("world");
    }

我们使用StringBuilder类来进行拼接的话,因为这是一个类,那么我们就要创建一个引用类型来引用这个StringBuilder对象。

然后,因为StringBuilder 是一个对象的引用,那么如果我直接用String类的引用类型对接收 StringBuilder的值,是不能接收的:

 那么,我们查看反汇编,其中使用的是 toString方法来进行转换:

这样进行赋值:

        String str = stringBuilder.toString();

 

 String和StringBuilder和StringBuffer的区别:

  •  String的拼接会产生大量的临时对象,StringBuffer和StringBuilder不会。
  • String拼接会被优化为StringBuilder的append()的拼接。
  • 后两者的当中的一些方法,是String中不具备的,比如:逆置方法。
  •  StringBuffer,StringBuilder 前两者和 String 的最大区别就在于,String的内容无法修改,而StringBuffer,StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer,StringBuilder

 逆置reverse()方法:

    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("hello");
        stringBuilder.reverse();
        System.out.println(stringBuilder);//olleh
    }

而且因为此处的 reverse()方法是对 StringBuilder 这个对象进行操作的,那么这个方法不需要定义一个String变量去接收 逆置之后的字符串(返回值),直接对 StringBuilder对象中的字符串进行修改。 

但是,也可以把结果赋值给另一个 StringBuilder 对象:

        StringBuilder stringBuilder1 = stringBuilder.reverse();
        System.out.println(stringBuilder1);//olleh

 这时候我们去打印这对象中的字符串,发现和之前逆置的字符串是一样的。

但是我们不能去给另一个类型的对象赋值,比如 StringBuilder的逆置字符串结果不能给 StringBuffer对象赋值,同样,反过来也是不行的:

 我们发现此时报错了。

String是如何产生大量的临时对象的呢?同样我们来查看反汇编代码:

    public static void main(String[] args) {
        String str = " ";
        for(int i = 0;i < 10;i++)
        {
            str += 'a';
        }
    }

 首先以会优化,创建了 一个 StringBuilder的对象,然后同样是使用append()方法两次,我们主要来看后面的goto语句:

 也就说,在return之前会先goto一下,goto到第5行,那么我们创建 StringBuilder对象是在第11行,那么也就说,在循环结束之前我们会创建很多个StringBuilder对象。

但是我们使用StringBuilder来拼接字符串就不会:

    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0;i < 10;i++)
        {
            stringBuilder.append('a');
        }
    }

 比如这个代码,我们来查看反汇编:

 他在第0 行创建了一个对象,然后我们来查看循环的goto语句:

 我们发现,它goto的是第10 行代码,那么在每一次循环中他不会再创建对象。

 

 那这个append()拼接,拼接的是一个对象,也就是说,不管我使用多少个append(),只要我前引用的是一个对象,那么拼接都是针对这个对象来进行拼接的,那么上述的代码还可以这样写:

        stringBuilder.append("hello").append("world");

 他也能实现这个同样的效果,那么他是如何实现这样的效果的呢?我们查看append()方法的源代码: 

 

 我们发现StringBuilder中的append()方法的返回值是this,也就是,这个方法返回的是这个类本身,那么作用在对象上,也就说是,这个方法返回的是append的对象本身,例如上述代码,当append("hello")方法调用完之后,返回调用修改之后的对象,那么此时这个代码就变成这个样子了:

 StringBuilder和StringBuffer的区别:

 我们分别查看StringBuilder和StringBuffer的append()方法的源代码:

 不管两个类中append如何实现的,return返回的都是this,但是StringBuffer相对于StringBuilder,多了一个synchronized关键字,

这个synchronized关键字,代表的是 线程安全 ,加了这个关键字,代表这个方法他是 线程安全的。

也就是说,StringBuilder 和 String 一般用于单线程

 而StringBuffer 一般用于多线程

而导致上面的原因就是因为 synchronized关键字的存在。而我们查看StringBuffer 类的源代码,发现里面的方法都是用 synchronized关键字修饰的:

 而在StringBuilder当中就没有这个关键词修饰。

注意:String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

  • String变为StringBuffer:利用StringBuffer的构造方法或append()方法
  • StringBuffer变为String:调用toString()方法
     

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中的StringBufferStringBuilder类是用于字符串操作的可变字符序列类。它们都具有类似的功能,但在某些方面有所不同。StringBuffer是线程安全的,适用于多线程环境下的字符串拼接和修改操作。而StringBuilder是非线程安全的,适用于单线程环境下的字符串操作,它的性能相对较高。 StringBufferStringBuilder类都提供了类似的方法,包括创建、追加、插入、删除、替换、反转等操作。可以使用append()方法在字符串末尾追加内容,使用insert()方法在指定位置插入内容,使用delete()方法删除指定位置的字符,使用replace()方法替换指定范围内的字符,使用reverse()方法反转字符串等。此外,它们还支持toString()方法将可变字符序列转换为字符串,以及length()方法获取字符序列的长度等常见操作。 在使用StringBufferStringBuilder类时,需要根据实际情况选择合适的类。如果在多线程环境下进行字符串操作,安全性是首要考虑因素,可以使用StringBuffer类。如果在单线程环境下进行字符串操作,并且对性能有较高要求,可以使用StringBuilder类。 总之,Java中的StringBufferStringBuilder类提供了灵活和高效的字符串操作方法,可以根据需要选择合适的类来处理字符串。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Java StringBufferStringBuilder](https://blog.csdn.net/sheng0113/article/details/124081818)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [面试题java StringBufferStringBuilder类常见操作和用法](https://download.csdn.net/download/qq_43797491/87906515)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chihiro1122

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

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

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

打赏作者

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

抵扣说明:

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

余额充值