java初学笔记-Lang包下常用类之__2.StringBuilder/StringBuffer类

1.字符串拼接问题

存在问题:
由于String类的对象内容不可改变, 所以每当进行字符串拼接时, 总是会在内存中创建一个新的对象。
如:

        //String类的对象内容不可改变,下面总共产生了三个字符串
        String s = "Hello";
        s += "World";
        System.out.println(s);  

2个字符串相加, 在字符串常量池中创建了3个字符串,“Hello”、“World”、“HelloWorld”。3个字符串相加, 会创建5个字符串…以此类推, 用这种方式进行字符串拼接效率低下。
String和StringBuilder内存模型
解决方法:
java.lang.StringBuilder 字符串缓冲区

StringBuilder类的对象底层也是一个数组, 但是没有被final修饰, 可以改变长度
StringBuilder类的对象是个变量, 进行字符串拼接时不用创建新的对象, 效率更高, 如果超出了容量, 会自动扩容
byte[] value = new byte[16];

java.lang.StringBuffer跟 StringBuilder十分相似

2.构造方法

根据API文档, StringBuilder类的常用构造方法有2个:

  • public StringBuilder() : 构造一个空的StringBuilder容器。
  • public StringBuilder(String str) : 构造一个StringBuilder容器, 并将字符串添加进去。

3.常用方法

  • public StringBuilder append(…) : 添加任意类型数据的字符串形式, 并返回当前对象本身。
  • public String toString(): 将当前StringBuilder对象转换为String对象。
  • public StringBuilder insert(int offset, Object obj) : 将对象插入指定索引位置,并返回当前对象本身
  • public StringBuilder reverse() : 反转字符串内容
public class testStringBuilder {
    public static void main(String[] args) {

        //String类的对象内容不可改变,下面总共产生了三个字符串
        String s = "Hello";
        s += "World";
        System.out.println(s);
        System.out.println("下面是StringBuilder类==================================");
        /**
         * StringBuilder类
         * 构造方法:
         *  - public StringBuilder() : 构造一个空的StringBuilder容器。
         *  - public StringBuilder(String str) : 构造一个StringBuilder容器, 并将字符串添加进去。
         *  - public StringBuilder insert(int offset, Object obj) : 将对象插入指定索引位置,并返回当前对象本身
         */
        StringBuilder sbd1 = new StringBuilder();
        StringBuilder sbd2 = new StringBuilder("abc");

        sbd1 = sbd1.append("123");//字符串拼接
        sbd1 = sbd1.append(sbd2);
        System.out.println(sbd1);

        sbd1.insert(1,0);//在指定索引位置插入对象
        System.out.println(sbd1);

        String str = sbd1.toString();//把StringBuilder对象转换为String对象
        System.out.println(str);

        System.out.println("下面是StringBuffer类==================================");
        /**
         * StringBuffer类,常用方法的使用跟StringBuilder类相同
         */
        StringBuffer sbf1 = new StringBuffer();
        StringBuffer sbf2 = new StringBuffer("abc");

        sbf1 = sbf1.append("123");//字符串拼接
        sbf1 = sbf1.append(sbf2);
        System.out.println(sbf1);

        sbf1.insert(1,0);//在指定索引位置插入对象
        System.out.println(sbf1);

        String str1 = sbf1.toString();//把StringBuffer对象转换为String对象
        System.out.println(str1);
        
         /**
         * 链式编程:方法的返回值是一个对象,可以根据对象继续调用方法
         */
        sbd1.append(1).append(2).append(3).append(4);
    }
}

扩展-StringBuilder、StringBuffer、String区别

以下引用自<java中String、StringBuffer和StringBuilder的区别(简单介绍)>[https://www.cnblogs.com/weibanggang/p/9455926.html]

概况

三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。

StringBuffer是线程安全,可以不需要额外的同步用于多线程中;
StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理, 但是速度就比StringBuffer快多了;
StringBuffer与StringBuilder两者共同之处: 可以通过append、insert进行字符串的操作。

String实现了三个接口:Serializable、Comparable、CarSequence
StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。

运行速度区别

一般情况下由快到慢: StringBuilder > StringBuffer > String
String最慢的原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

另外,有时候我们会这样对字符串进行赋值
String str=“abc”+“de”;
这样String的速度比使用StringBuilder拼接的运行速度要快很多, 这是JVM虚拟机编译优化的结果。虚拟机在编译阶段直接将右侧字符串拼接完成, 运行阶段只是单纯的赋值过程, 相当于 String str=“abcde”; 所以速度很快。

线程安全区别

在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

缓冲区

以下引用自<StringBuffer 和 StringBuilder 的 3 个区别>https://segmentfault.com/a/1190000017909550

StringBuffer 代码片段:

private transient char[] toStringCache;

@Override
public synchronized String toString() {
    if (toStringCache == null) {
        toStringCache = Arrays.copyOfRange(value, 0, count);
    }
    return new String(toStringCache, true);
}

StringBuilder 代码片段:

@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

可以看出,StringBuffer 调用toString()方法需要使用缓存区的 toStringCache 拷贝一次字符数组, 再构造一个字符串。
而 StringBuilder 则直接通过字符数组构造一个字符串。
这也是对 StringBuffer 缓冲区的一个优化,而且StringBuffer 的这个toString 方法仍然是同步的。

总结

String:适用于少量的字符串操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
String、StringBuilderStringBuffer之间的区别主要有以下几点: 1. 可变性: String是不可变字符串,即一旦创建就不能修改。而StringBuilderStringBuffer是可变字符串,可以随意修改其内容。 2. 线程安全性: StringBuffer是线程安全的,可以在多线程环境下使用,而StringBuilder是线程不安全的,不适用于多线程环境。这是因为StringBuffer的方法都使用了synchronized关键字来保证线程安全性,而StringBuilder没有。 3. 执行速度: 在执行速度方面,StringBuilder的性能最好,其次是StringBuffer,而String的执行速度最慢。这是因为String每次对字符串进行修改时,都会创建一个新的String对象,而StringBuilderStringBuffer则是直接在原有的对象上进行修改,避免了创建新对象的开销。 综上所述,String是不可变的字符串,StringBuilderStringBuffer是可变的字符串,StringBuilder是线程不安全的但执行速度较快,而StringBuffer是线程安全的但执行速度稍慢。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [String 和 StringBuilder 以及 StringBuffer的区别](https://blog.csdn.net/weixin_43682323/article/details/128036953)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [String/StringBuilder/StringBuffer之间的区别](https://blog.csdn.net/weixin_33826268/article/details/92944578)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [6. String StringBuffer StringBuilder 区别](https://blog.csdn.net/qq_44791484/article/details/115363705)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

code tea

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

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

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

打赏作者

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

抵扣说明:

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

余额充值