String StringBuffer StringBuilder

本文深入探讨了Java中String、StringBuffer和StringBuilder的区别,包括它们的线程安全性、内部实现和性能表现。通过实例演示了在不同场景下如何选择最适合的字符串类型。

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

共同点:

  • 都是处理string类型的数据 这三个类都是来自java.lang中
  • String和StringBuffer使用的是char数组为数据结构
  • StringBuilder在String上直接进行操作

不同点

  • String,StringBuilder线程不安全
  • StringBuffer线程安全
  • String多有操作都是基于新对象,返回新对象
  • StringBuffer,StringBuilder所有操作都在现对象中操作

1.String

结构图
在这里插入图片描述

1)String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。在早期的JVM实现版本中,被final修饰的方法会被转为内嵌调用以提升执行效率。而从Java
SE5/6开始,就渐渐摈弃这种方式了。因此在现在的Java
SE版本中,不需要考虑用final去提升方法调用效率。只有在确定不想让该方法被覆盖时,才将方法设置为final。
2)上面列举出了String类中所有的成员属性,从上面可以看出String类其实是通过char数组来保存字符串的。
> 无论是substring、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。也就是说进行这些操作后,最原始的字符串并没有被改变。
在这里要永远记住一点:
“对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象”。

2.StringBuffer

在这里插入图片描述

3.StringBuilder

在这里插入图片描述

下面对上面的执行结果进行一般性的解释:
1)对于直接相加字符串,效率很高,因为在编译器便确定了它的值,也就是说形如"I"+“love”+“java”;
的字符串相加,在编译期间便被优化成了"Ilovejava"。这个可以用javap -c命令反编译生成的class文件进行验证。
对于间接相加(即包含字符串引用),形如s1+s2+s3; 效率要比直接相加低,因为在编译器不会对引用变量进行优化。
2)String、StringBuilder、StringBuffer三者的执行效率:
StringBuilder > StringBuffer > String
当然这个是相对的,不一定在所有情况下都是这样。
比如String str = “hello”+ "world"的效率就比 StringBuilder st = new
StringBuilder().append(“hello”).append(“world”)要高。
因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用:
当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
参考:https://www.cnblogs.com/dolphin0520/p/3778589.html

前面的博客已经写得很详细啦,我就做个小实验,证明下线程安全问题吧:

public class StringThreadSecurity {
    public String string = new String();
    public StringBuilder stringBuilder = new StringBuilder();
    public StringBuffer stringBuffer = new StringBuffer();

    public static void main(String[] args) throws InterruptedException {
        StringThreadSecurity test=new StringThreadSecurity();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        CountDownLatch countDownLatch = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            MyThreadTestString myThread = new MyThreadTestString(countDownLatch,test);
            executor.execute(myThread);
        }
        countDownLatch.await();
        executor.shutdown();
        System.out.println("string "+test.string.length());
        System.out.println("stringBuilder "+test.stringBuilder.length());
        System.out.println("stringBuffer "+test.stringBuffer.length());
    }
}

class MyThreadTestString extends Thread {

    private CountDownLatch countDownLatch;
    private StringThreadSecurity test;

    public MyThreadTestString(CountDownLatch countDownLatch,StringThreadSecurity test) {
        this.countDownLatch = countDownLatch;
        this.test=test;
    }


    public void run() {
        try {
            for (int i = 0; i < 1000; i++) {
                test.string = test.string + 'a';
                test.stringBuilder.append('a');
                test.stringBuffer.append('a');
            }
        } finally {
            countDownLatch.countDown();
        }

    }
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190409215446413.png
3个线程循环1000次,字符创长度应该是3000个,可以看出StringBuffer的确是线程安全的。

内容概要:文章介绍了DeepSeek在国内智能问数(smart querying over data)领域的实战应用。DeepSeek是一款国内研发的开源大语言模型(LLM),具备强大的中文理解、推理和生成能力,尤其适用于企业中文环境下的智能问答、知识检索等。它具有数据可控性强的特点,可以自部署、私有化,支持结合企业内部数据打造定制化智能问数系统。智能问数是指用户通过自然语言提问,系统基于结构化或非结构化数据自动生成精准答案。DeepSeek在此过程中负责问题理解、查询生成、多轮对话和答案解释等核心环节。文章还详细展示了从问题理解、查询生成到答案生成的具体步骤,并介绍了关键技术如RAG、Schema-aware prompt等的应用。最后,文章通过多个行业案例说明了DeepSeek的实际应用效果,显著降低了数据使用的门槛。 适合人群:从事数据分析、企业信息化建设的相关从业人员,尤其是对智能化数据处理感兴趣的业务和技术人员。 使用场景及目标:①帮助业务人员通过自然语言直接获取数据洞察;②降低传统BI工具的操作难度,提高数据分析效率;③为技术团队提供智能问数系统的架构设计和技术实现参考。 阅读建议:此资源不仅涵盖了DeepSeek的技术细节,还提供了丰富的实战案例,建议读者结合自身业务场景,重点关注DeepSeek在不同行业的应用方式及其带来的价值。对于希望深入了解技术实现的读者,可以进一步探索Prompt工程、RAG接入等方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值