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

2023/11/30 3:23:05

系列文章目录

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


文章目录

  • 系列文章目录
  • 前言
  • 1、特性
    • 1.1、操作StringBuffer不会生成新的对象
    • 1.2、对比操作String会生成新的对象
  • 2、线程安全
    • 2.1、StringBuffer线程安全
    • 2.2、StringBuilder线程不安全
  • 3、值长度与扩容
    • 3.1、扩容长度:(S >> 1) + 2 代码验证
    • 3.2、扩容长度:V + VN代码验证


前言

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象;
StringBuffer是线程安全的,StringBuilder不是;
扩容规则会根据新值+旧值的长度计算;
在这里插入图片描述

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
    在这里插入图片描述
    3、(S >> 1) + 2 < V + VN , 扩容长度:V + VN

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

在这里插入图片描述

     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代码验证

在这里插入图片描述

     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
---------------------------------------

http://www.jnnr.cn/a/590966.html

相关文章

Spring Boot 中的 Criteria 是什么,如何使用?

Spring Boot 中的 Criteria 是什么&#xff0c;如何使用&#xff1f; 介绍 Spring Boot 是一个流行的 Java Web 开发框架&#xff0c;它提供了一些强大的工具和库&#xff0c;使得开发 Web 应用程序变得更加容易。其中之一是 Criteria API&#xff0c;它提供了一种类型安全的…

JVM理论(二)类加载子系统

类加载流程 类加载流程 类加载器子系统负责从文件系统或者网络中加载class文件,class文件的文件头有特定的文件标识(CAFEBABE是JVM识别class文件是否合法的依据)classLoader只负责文件的加载,而执行引擎决定它是否被执行加载类的信息存放在运行时数据区的方法区中,方法区还包括…

启动项目报错,如何分析pom

报错信息如下 Caused by: java.lang.NoClassDefFoundError: org/springframework/core/metrics/ApplicationStartup 报错说找不到ApplicationStartup这个类&#xff0c;到项目中查看pom的dependency 我的项目引入了两个依赖 <parent><groupId>org.springframewor…

使用electron打包spring-boot+vue项目开发桌面exe端项目一站式全部解决!专栏有解决报错文章

准备工具 前端:node.js 14以下(直接安装 node.js 即可) 后端:jre 1.8(必须1.8) 工具: Bat_To_Exe_ConverterInno_Setup 汉化版(英文版不支持简体中文,打包出来的安装界面是英文的)我以及给大家汇总完毕直接点击进去下载即可 https://pan.baidu.com/s/1XoA0tj3b4Q…

C#基础学习_构造方法

C#基础学习_构造方法 在构造方法中添加初始化内容; 通过使用构造方法,可以简化对象初始化代码。 无参数的构造方法: public Student(){StudentID = 12345;StudentName = "djichsdi";}带参数的构造方法(构造方法同样可以重载&

每日浅读SLAM论文——简析LIO-SAM

文章目录 Overview雷达里程计IMU预积分GPS回环代码结构解析 今天讲一篇经典的LIO&#xff08;LiDAR-Inertial Odometry&#xff09;SLAM论文——LIO-SAM。 雷达里程计由于其高鲁棒性、较低成本&#xff08;二维雷达不贵、三维雷达价格也在降、IMU不太贵&#xff09;&#xff0c…

【海量数据挖掘/数据分析】之 决策树模型(决策树模型、决策树构成、决策树常用算法、决策树性能要求、信息增益、信息增益计算公式、决策树信息增益计算实例)

【海量数据挖掘/数据分析】之 决策树模型&#xff08;决策树模型、决策树构成、决策树常用算法、决策树性能要求、信息增益、信息增益计算公式、决策树信息增益计算实例&#xff09; 目录 【海量数据挖掘/数据分析】之 决策树模型&#xff08;决策树模型、决策树构成、决策树常…

删除排序链表中的重复元素(保留一个重复元素或不保留重复元素)

题目1&#xff1a;给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。&#xff08;重复元素不全部都删除&#xff0c;需要保留一个&#xff09; 解题思路&#xff1a; 遍历链表&#xff0c;找到重复元素…

第三章 SSD存储介质:闪存 3.1

3.1 闪存物理结构 闪存芯片从小到大依此是由&#xff1a;cell&#xff08;单元&#xff09;、page&#xff08;页&#xff09;、block&#xff08;块&#xff09;、plane&#xff08;平面&#xff09;、die&#xff08;核心&#xff09;、NAND flash&#xff08;闪存芯片&#…

矩阵系统源码智能回复私信场景开发

抖音矩阵系统源码智能回复私信场景开发 一、要想开发私信功能开发者需要准备的工作 开发者需要先对接官方api接口以及去申请api提交审核&#xff0c;目前需要了解官方对开发者对该能力开发权限的功能符合开发需求&#xff0c;其次需要了解官方私信触达的规则 1.申请流程&…

安装git工具

下载安装地址&#xff1a; Git - Downloading Package (git-scm.com) 命令安装&#xff1a;创建文件夹下载路径 启动powershell 输入命令&#xff1a;winget install --id Git.Git -e --source winget 等待下载安装

【SQL】查找多个表中相同的字段

--查找字段所在 SELECTbb.TABLE_NAME,bb.COLUMN_NAME ,aa.COLUMN_ID,aa.DATA_TYPE,aa.DATA_LENGTH ,bb.COMMENTS FROMuser_tab_cols aa JOIN user_col_comments bb ONaa.TABLE_NAME bb.TABLE_NAMEAND aa.COLUMN_NAME bb.COLUMN_NAME JOIN dba_objects cc ONbb.TABLE_NAME cc…

Jenkins 参数化构建

目录 前言&#xff1a; 以下是Jenkins官方的介绍&#xff1a; 首先新建一个自由风格的job&#xff0c;然后勾选“This project is parameterized”&#xff0c;如下图&#xff1a; 勾选参数构建 choice parameterized&#xff1a; 选项&#xff1a; 使用参数&#xff1a;…

【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用

【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用 第三章 微信小程序WXML、JS、JSON、WXSS作用 文章目录 【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用前言一、WXML是什么&#xff1f;二、JS是什么&#xff1f;三、JSON是什么&#xff1f;四、WXSS是什…

docker运行 mycli

1. 制作镜像 1.1 Dockerfile: FROM python:3.8 ENV MYSQL_HOST192.168.1.108 ENV MYSQL_PWDroot RUN apt-get update && apt-get install -y less RUN pip3 install mycli ENTRYPOINT ["mycli"] 注意 python:3.8 pip3 mycli 具有版本限制的,如果改了版…

Istio 深入理解数据平面组件 Envoy

ingress control承载了控制面和数据面的一个职责&#xff0c;在control里面有一个process&#xff0c;这个进程就承担了反向代理的能力&#xff0c;当有任何请求发过来的时候&#xff0c;会被nginx接收到这个请求并且被转发&#xff0c;基于的规则由ingress control动态配置的&…

Blender--原理化体积

“原理化体积 着色器将所有体积着色组件组合到一个易于使用的节点中。该节点含有散射&#xff0c;吸收和黑体辐射属性&#xff0c;因此&#xff0c;可以仅仅使用该着色器节点对烟雾和火焰等进行渲染。” 官方文档介绍&#xff1a;原理化体积 — Blender Manual 可以用于实现丁…

【Linux】oh-my-zsh终端配置

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍oh-my-zsh终端配置。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&am…

港科夜闻|香港科大(广州)及香港科大学者19篇论文入选数据库顶会ACM SIGMOD 2023...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大(广州)及香港科大学者19篇论文入选数据库顶会ACM SIGMOD 2023。2023年6月18-23日&#xff0c;数据库领域顶级会议ACM SIGMOD 2023于美国西雅图顺利举行。ACM SIGMOD 会议作为数据库系统领域历史最悠久且最权威的…

kotlin Flow系列之 - 冷流SafeFlow源码解析之 - Safe在那里?

本文涉及源码基于kotlinx-coroutines-core-jvm:1.7.1 kotlin 协成系列文章: 你真的了解kotlin中协程的suspendCoroutine原理吗? Kotlin Channel系列&#xff08;一&#xff09;之读懂Channel每一行源码 kotlin Flow系列之-冷流SafeFlow源码解析之 - Safe在那里&#xff1f; ko…
最新文章