[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析

这篇具有很好参考价值的文章主要介绍了[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄
🌹简历模板、学习资料、面试题库、技术互助

🌹文末获取联系方式 📝

系列文章目录

[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析
[Java基础] 数组应用及源码分析
[Java基础] String,分析内存地址,源码



前言

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象;
StringBuffer是线程安全的,StringBuilder不是;
扩容规则会根据新值+旧值的长度计算;
[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析,Java基础,数据结构与算法,java,python,linux

1、特性

1.1、操作StringBuffer不会生成新的对象

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

	StringBuffer stringBuffer = new StringBuffer();
    log.info("内存地址:{}" , ObjectCommon.toString(stringBuffer) );
    System.out.println("---------------------------------------");

    stringBuffer.append("Kelvin");
    log.info("内存地址:{}" , ObjectCommon.toString(stringBuffer) );
    System.out.println("---------------------------------------");

    stringBuffer.append("!");
    log.info("内存地址:{}" , ObjectCommon.toString(stringBuffer) );
    System.out.println("---------------------------------------");
  • 结果(三次添加数据,内存地址都是一样的)
23:41:06.936 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 内存地址:java.lang.StringBuffer@58d25a40
---------------------------------------
23:41:06.946 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 内存地址:java.lang.StringBuffer@58d25a40
---------------------------------------
23:41:06.947 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 内存地址:java.lang.StringBuffer@58d25a40

1.2、对比操作String会生成新的对象

	String str = new String();
    log.info("内存地址:{}" , ObjectCommon.toString(str) );
    System.out.println("---------------------------------------");

    str += "Kelvin";
    log.info("内存地址:{}" , ObjectCommon.toString(str) );
    System.out.println("---------------------------------------");

    str += "!";
    log.info("内存地址:{}" , ObjectCommon.toString(str) );
    System.out.println("---------------------------------------");
  • 结果(三次添加数据,内存地址都是不一样的)
23:45:41.723 [main] INFO com.kelvin.spiderx.test.StringTest - 内存地址:java.lang.String@58d25a40
---------------------------------------
23:45:41.739 [main] INFO com.kelvin.spiderx.test.StringTest - 内存地址:java.lang.String@626b2d4a
---------------------------------------
23:45:41.740 [main] INFO com.kelvin.spiderx.test.StringTest - 内存地址:java.lang.String@5e91993f

2、线程安全

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

2.1、StringBuffer线程安全

StringBuffer的方法都增加了synchronized,包括:添加、删除、截取、反转、toString等方法。
在加锁的情况下,只有一个线程能进行操作,所以是线程安全的。

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

	@Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
    }

	@Override
    public synchronized String substring(int start, int end) {
        return super.substring(start, end);
    }

	@Override
    public synchronized StringBuffer reverse() {
        toStringCache = null;
        super.reverse();
        return this;
    }

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

2.2、StringBuilder线程不安全

	@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    
    @Override
    public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }

3、值长度与扩容

旧值长度 = V ;新值长度 = NV ; 所占空间 = S

  • StringBuffer、StringBuilder在初始化数据时,可以指定初始空间(不指定,取默认值16);
  • 在添加数据时会按照以下规则扩容
    1、V + VN <= S ,不会扩容
    2、S < V + VN <= (S >> 1) + 2 , 会扩容,扩容长度:(S >> 1) + 2
    [Java基础] StringBuffer 和 StringBuilder 类应用及源码分析,Java基础,数据结构与算法,java,python,linux
    3、(S >> 1) + 2 < V + VN , 扩容长度:V + VN

3.1、扩容长度:(S >> 1) + 2 代码验证

[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析,Java基础,数据结构与算法,java,python,linux

     StringBuffer stringBuffer = new StringBuffer(10);
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("Kelvin");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("!");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("1234567890");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

结果:

00:33:15.931 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:0
00:33:15.938 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:33:15.938 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:6
00:33:15.938 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:33:15.938 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:7
00:33:15.939 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:33:15.939 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:17
00:33:15.939 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:22
---------------------------------------

3.2、扩容长度:V + VN代码验证

[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析,Java基础,数据结构与算法,java,python,linux

     StringBuffer stringBuffer = new StringBuffer(10);
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("Kelvin");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("!");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

     stringBuffer.append("12345678901234567890");
     log.info("值长度:{}" , stringBuffer.length());
     log.info("所占空间长度:{}" , stringBuffer.capacity());
     System.out.println("---------------------------------------");

结果:

00:38:43.250 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:0
00:38:43.257 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:6
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:7
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:10
---------------------------------------
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 值长度:27
00:38:43.258 [main] INFO com.kelvin.spiderx.test.StringBufferTest - 所占空间长度:27
---------------------------------------

相关项目实现推荐:

查看更多博主首页更多实战项目 >>>

大家点赞、收藏、关注、评论啦 、查看👇🏻👇🏻👇🏻微信公众号获取联系👇🏻👇🏻👇🏻

WX:biancheng2019

精彩专栏推荐:

构建SpringCloud alibaba项目

Vue3实战

构建SpringBoot 项目文章来源地址https://www.toymoban.com/news/detail-533684.html

到了这里,关于[Java基础] StringBuffer 和 StringBuilder 类应用及源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java StringBuffer和StringBuilder类

    由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。与String不同的是,StringBuffer和StringBuilder是对字符串本身进行修改,并且不产生新的对象,而String是产生新的字符串进行修改。 由于StringBuffer的方法和StringBuilder方法大部分是相同的,所

    2024年02月12日
    浏览(25)
  • Java中的String、StringBuffer和StringBuilder

    在 Java 中,字符串是最常用的数据类型之一。 Java 中有三种处理字符串的方式:String、StringBuffer 和 StringBuilder。它们都被设计为处理字符串操作,但是它们之间有所不同。本篇博客将会介绍 String、StringBuffer 和 StringBuilder 的区别以及如何在 Java 中使用这些类型。 在 Java 中,

    2024年02月02日
    浏览(25)
  • Java常用API:StringBuilder、StringBuffer、StringJoiner

    如果多用户共同使用这个StringBuilder时是不安全。 因为这个是字符串类型的,所有遍历后 要+“” 改成字符串类型。最后要用s.toString()变成字符串

    2024年02月15日
    浏览(24)
  • JAVA - 字符串工具类StringBuilder和StringBuffer

    目录 文章目录 前言 二.常用方法演示 1.append()用于将指定的字符串添加到当前StringBuilder对象的末尾 2.delete():用于删除StringBuilder对象中指定位置的字符。  3.insert():用于在指定位置插入指定字符串。  4.replace():用于替换指定位置的字符或字符串。 5.reverse():用于将StringBu

    2024年02月06日
    浏览(39)
  • 【java】关于String、StringBuffer和StringBuilder的那些事

      目录 一、String 1、构造方法 2、字符串的不可变性 3、字符串的比较 4、 String的常用方法: 二、StringBuider和StringBuffer 1、字符串的拼接 2、StringBuider与StringBuffer 总结     String类提供的构造方式非常多,常用的就以下两种:   注意: 1、String 是引用类型,内部并不存储字符串

    2024年04月10日
    浏览(28)
  • Java字符串知多少:String、StringBuffer、StringBuilder

    String 是 Java 中使用得最频繁的一个类了,不管是作为开发者的业务使用,还是一些系统级别的字符使用, String 都发挥着重要的作用。 String 是 不可变 的、 final 的,不能被继承,且 Java 在运行时也保存了一个字符串池(String pool) ,就使得 String 变得很特殊。 实现三个接口:

    2024年02月06日
    浏览(39)
  • 从零开始学Java59之StringBuilder与StringBuffer

    最近的这几篇文章,我们一直在给大家讲解字符串相关的内容。 其实字符串按照可变性,可以分为不可变字符串与可变字符串。 我们前面学习的String就属于不可变字符串,因为理论上一个String字符串一旦定义好,其内容就不可再被改变,这些内容我们已经在前面都学习过了

    2024年02月05日
    浏览(23)
  • 【JAVA】String ,StringBuffer 和 StringBuilder 三者有何联系?

    个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 在之前的文章中我们介绍了JAVA中String的运用方法,事实上在JAVA字符串操作中仅仅只知道String方法是远远不够的,今天我们要介绍的 StringBuffer 和 StringBuilder 在字符串操作中同样占据总要地位。 和 String 类不同的是,S

    2024年02月14日
    浏览(31)
  • 【后端面经-Java】String与StringBuffer与StringBuilder的比较

    目录 1. String 2. StringBuffer 3. StringBuilder 4. 性能提升 5. 总结和比较 面试模拟 参考资料 不可变 查看 String 源码如下:由源码可知,String中存储数据的数组被 final 修饰,因此是不可变的 运算和操作 创建对象 创建对象有两种方式:两种方式都会在栈中创建一个字符串变量

    2024年02月16日
    浏览(34)
  • Java 21的StringBuilder和StringBuffer新增了一个repeat方法

    发现Java 21的 StringBuilder 和 StringBuffer 中多了repeat方法: 根据名字猜猜是干嘛的?试试下面的代码: 最后会输出: 另一个 repeat 方法第一个参数是 codePoint ,指得应该是UniCode字符集中的codePoint,所以这个方法的repeat是针对UniCode字符的。 一时间似乎想不到什么特别大的用户,就

    2024年02月08日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包