一文简单回顾Java中的String、StringBuilder、StringBuffer

news2025/1/30 12:34:20

简单说下String、StringBuilder、StringBuffer的区别

  • String、StringBuffer、StringBuilder在Java中都是用于处理字符串的,它们之间的区别是String是不可变的,平常开发用的最多,当遇到大量字符串连接的时候,就用StringBuilder,它不会生成很多新的对象,StringBuffer和StringBuilder类似,但每个方法上都加了synchronized 关键字,所以是线程安全的;

接下来说下String的特点

  • String类的对象是不可变的,也就是说,一旦一个String对象被创建,它所包含的字符串内容是不可改变的;
  • 每次对String对象进行修改操作,比如拼接、替换等操作时,实际上都会生成一个新的String对象,而不是修改原有对象。这可能会导致内存和性能开销,尤其是在大量字符串操作的情况下;

继续说下StringBuilder的特点

  • StringBuilder提供了一系列的方法来进行字符串的增删改查操作,这些操作都是直接在原有字符串对象的底层数组上进行的,而不是生成新的String对象;
  • StringBuilder不是线程安全的。这意味着在没有外部同步的情况下,它不适用于多线程环境;
  • 相比于String,在进行频繁的字符串修改操作时,StringBuilder能提供更好的性能。Java中的字符串连+操作其实就是通过StringBuilder实现的;

StringBuffer的特点

  • StringBuffer和StringBuidler类似,但StringBuffer是线程安全的,方法前面都加了synchronized关键字;

总结下三者的使用场景

  • String:适用于字符串内容不会改变的场景,比如说作为HashMap的key
  • StringBuilder:适用于单线程环境下需要频繁修改字符串内容的场景,比如在循环中拼接或修改字符串,是String的完美替代品
  • StringBuffer:现在不怎么用了,因为一般不会在多线程场景下去频繁的修改字符串内容;

延申问下String是不可变类吗?字符串拼接是如何实现的?

  • String是不可变的,这意味着一旦一个String对象被创建,其存储的文本内容就不能被改变。这是因为:
    1. 不可变性使得String对象在使用中更加安全,因为字符串经常用作参数传递给其他Java方法,例如网络连接、打开文件等
      如果String是可变的,这些方法调用的参数值就可能在不知不觉中被改变,从而导致网络连接被篡改,文件被莫名奇妙地修改等问题
    2. 不可变的对象因为状态不会改变,所以更容易进行缓存和重用。字符串常量池的出现正是基于这个原因;
      当代码中出现相同的字符串字面量时,JVM会确保所有的引用都指向常量池中的同一个对象,从而节约内存;
    3. 因为String的内容不会变,所以它的哈希值也就固定不变。这使得String对象特别适合作为HashMap或HashSet等集合的键,因为计算哈希值只需要进行一次,提高了哈希操作的效率;

接下来回答第二个问题,字符串是如何实现的呢?

  • 例如String是不可变的,因此通过“+”操作符进行的字符串拼接,会生成新的字符串对象。
String a = "hello ";
String b = "world!";
String ab = a + b;
  • a 和 b 是通过双引号定义的,所以会在字符串常量池中,而 ab 是通过“+”操作符拼接的,所以会在堆中生成一个新的对象。

在这里插入图片描述

Java 8 时,JDK 对“+”号的字符串拼接进行了优化,Java 会在编译期基于 StringBuilder 的 append 方法进行拼接。
上面的代码相当于:

String a = "hello ";
String b = "world!";
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
String ab = sb.toString();

因此,如果笼统地讲,通过加号拼接字符串时会创建多个 String 对象是不准确的。因为加号拼接在编译期还会创建一个 StringBuilder 对象,最终调用 toString() 方法的时候再返回一个新的 String 对象。

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

那除了使用 + 号来拼接字符串,还有 StringBuilder.append()String.join() 等方式。

还想问下,如何保证String不可变呢?

  1. String内部类使用一个私有的字符数组来存储字符串数据。这个字符数组在创建字符串时被初始化,之后不允许被修改

    private final char value[];
    
  2. String类没有提供任何可以修改其内容的公共方法,像concat这些看似修改字符串的操作,实际上都是返回一个新创建的字符串对象,而原始字符串对象保持不变

    public String concat(String str) {
        if (str.isEmpty()) {
            return this;
        }
        int len = value.length;
        int otherLen = str.length();
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
    
  3. String类本身被声明为final,这意味着它不能被继承。这防止了子类可能通过添加修改方法来改变字符串内容的可能性;

    public  final class String
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2284890.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matlab中,fill命令用法

在 MATLAB 中,fill 命令用于创建填充多边形的图形对象。使用 fill 可以在二维坐标系中绘制填充的区域,通常用于绘制图形的背景或显示数据分布。 基本语法 fill(X, Y, C)X 和 Y 是同样长度的向量,定义了多边形的顶点坐标。C 是颜色&#xff0…

计算机网络之链路层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记,就不再多余写了,直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…

lib.exe正确用法winhv.lib生成方法

lib.exe /def:winhv.def /OUT:winhv.lib /machine:x64 winhv.def注意是 winhv.sys要不然会变成dll LIBRARY winhv.sys EXPORTSWinHvAllocateOverlayPagesWinHvDisablePartitionVtlWinHvDisableVpVtlWinHvEnablePartitionVtlWinHvEnableVpVtlWinHvFreeOverlayPagesWinHvGetCurr…

react-bn-面试

1.主要内容 工作台待办 实现思路: 1,待办list由后端返回,固定需要的字段有id(查详细)、type(本条待办的类型),还可能需要时间,状态等 2,一个集中处理待办中转路由页,所有待办都跳转到这个页面…

Linux:一切皆文件

**文件描述符**:它是一种特殊的索引,本质上是进程中file_struct结构体成员fd_array数组的下标。在Linux等系统中,文件描述符是一个非负整数,用于标识打开的文件,是内核为了高效管理已被打开的文件所创建的索引。通过文…

【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令

文章目录 指令格式(重点)1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…

项目集成Nacos

文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…

QT交叉编译环境搭建(Cmake和qmake)

介绍一共有两种方法(基于qmake和cmake): 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别:CMake 和 qmake 都是自动化构建工具,用于简化构建过程,管理编译设置&…

[cg] 使用snapgragon 对UE5.3抓帧

最近想要抓opengl 的api,renderdoc在起应用时会闪退(具体原因还不知道),试了下snapgraon, 还是可以的 官网需要注册登录后下载,官网路径:Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…

物业巡更系统在现代社区管理中的优势与应用探讨

内容概要 在现代社区管理中,物业巡更系统正逐渐成为一种不可或缺的工具。结合先进的智能技术,这些系统能够有效地提升社区管理的各个方面,尤其是在巡检效率和信息透明度方面。通过实时记录巡检数据,物业管理人员能够确保工作人员…

速通Docker === Docker Compose

目录 Docker Compose 简介 Docker Compose 常用命令 使用 Docker Compose 启动 WordPress 普通启动方式(使用 Docker 命令) 使用 Docker Compose 启动 Docker Compose 的特性 Docker Compose 简介 Docker Compose 是一个用于定义和运行多容器 Dock…

Spring MVC 综合案例

目录 一. 加法计算器 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 3. 服务器端代码 4. 运行测试 二. 用户登录 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 (1) 登录界面接口 (2) 首页接口 3. 服务器端代码 4. 运行测试 三. 留言板 1. 准备…

数据分析系列--③RapidMiner算子说明及数据预处理

一、算子说明 1 新建过程 2 算子状态灯 状态灯说明: (1)状态指示灯: 红色:指示灯说明有参数未被设置或输入端口未被连接等问题; 黄色:指示灯说明还未执行算子,不管配置是否基本齐全; 绿色:指示灯说明一切正常,已成功执行算子。 (2)三角…

NLP自然语言处理通识

目录 ELMO 一、ELMo的核心设计理念 1. 静态词向量的局限性 2. 动态上下文嵌入的核心思想 3. 层次化特征提取 1. 双向语言模型(BiLM) 2. 多层LSTM的层次化表示 三、ELMo的运行过程 1. 预训练阶段 2. 下游任务微调 四、ELMo的突破与局限性 1. 技术突破 2. …

Time Constant | RC 和 RL 电路中的时间常数

注:本文为 “Time Constant” 相关文章合辑。 机翻,未校。 How To Find The Time Constant in RC and RL Circuits June 8, 2024 💡 Key learnings: 关键学习点: Time Constant Definition: The time constant (τ) is define…

无心剑七绝《除夕快乐》

七绝除夕快乐 除旧迎新瑞气扬 夕阳烂漫映红妆 快言美酒佳肴味 乐享天伦福满堂 2025年1月28日 平水韵七阳平韵 无心剑这首七绝以“除夕快乐”为题,巧妙地运用了藏头手法,将“除夕快乐”四字分别嵌入诗的每一句首字,构思精巧,富有新…

Object类(3)

大家好,今天继续给大家介绍一下object类中的方法,那么话不多说,来看。 hashcode()这个方法,帮我们算了一个具体的对象位置,这里面涉及到数据结构,简单认为它是个内存地址,然后调用Integer.toHexString ()将这个地址以16进制输出。 该方法是一…

GPU上没程序在跑但是显存被占用

原因:存在僵尸线程,运行完但是没有释放内存 查看僵尸线程 fuser -v /dev/nvidia*关闭僵尸线程 pkill -9 -u 用户名 程序名 举例:pkill -9 -u grs python参考:https://blog.csdn.net/qq_40206371/article/details/143798866

2007-2020年各省国内专利申请授权量数据

2007-2020年各省国内专利申请授权量数据 1、时间:2007-2020年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区名称、年份、国内专利申请授权量(项) 4、范围:31省 5、指标解释:专利是专利权的简称&…

python:洛伦兹变换

洛伦兹变换(Lorentz transformations)是相对论中的一个重要概念,特别是在讨论时空的变换时非常重要。在四维时空的背景下,洛伦兹变换描述了在不同惯性参考系之间如何变换时间和空间坐标。在狭义相对论中,洛伦兹变换通常…