java基础之String、StringBuilder、StringBuffer的异同

目录

概述

String为何不可变,StringBuilder和StringBuffer为何可变

StringBuffer为何线程安全的,而StringBuilder为何非线程安全

三者性能分析

使用场景


概述

String、StringBuilder和StringBuffer都是用来处理字符串的类,底层都是通过char[]数组实现的。(jdk1.8及之前)

String是不可变的(线程安全的),StringBuilder和StringBuffer是可变的。StringBuffer是线程安全的,而StringBuilder是非线程安全的。具体如下:

String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;

StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。

如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。

下面我们从三个维度:可变性、线程安全性、性能来分析区别。

String为何不可变,StringBuilder和StringBuffer为何可变

String部分源码


public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];//。。。。。。。。。。。。。。。。。。
}

String类被声明为final,这意味着它不能被继承。那么他里面的方法就是没办法被覆盖的。
用final修饰字符串内容的char[] (从JDK 1.9开始,char[]变成了byte[]),由于该数组被声明为final,一旦数组被初始化,就不能再指向其他数组
String类没有提供用于修改字符串内容的公共方法。例如,没有提供用于追加、删除或修改字符的方法。如果需要对字符串进行修改,会创建一个新的String对象。所以说String是不可变的。

与String不同StringBuilder和StringBuffer底层封装的char[]并没有用final修饰,这意味着它是可以修改的。

StringBuilder部分源码

public final class StringBuilderextends AbstractStringBuilderimplements Serializable, CharSequence
{//。。。。。。。。。。。。。。。。。
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {/*** The value is used for character storage.*/char[] value;//。。。。。。。。。。。。。
}

StringBuffer部分源码

public final class StringBufferextends AbstractStringBuilderimplements Serializable, CharSequence
{//。。。。。。。。。。。。。。。。
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {/*** The value is used for character storage.*/char[] value;//。。。。。。。。。。。。。。。。。。。。。。。
}

StringBuffer为何线程安全的,而StringBuilder为何非线程安全

StringBuffer是线程安全的,它的方法都使用了synchronized关键字进行同步。在每个方法内部,通过加锁(synchronized)来确保在多线程环境下的安全访问。这意味着当一个线程访问StringBuffer的方法时,其他线程需要等待锁释放后才能执行相应的方法。因此,StringBuffer适用于多线程环境下对字符串的修改操作。

    //StringBuffer部分源码@Overridepublic synchronized StringBuffer append(Object obj) {toStringCache = null;super.append(String.valueOf(obj));return this;}@Overridepublic synchronized StringBuffer append(String str) {toStringCache = null;super.append(str);return this;}

而StringBuilder则没有使用synchronized关键字进行同步,它是非线程安全的。这样可以提高性能,因为不需要进行锁的获取和释放操作。但是,在多线程环境下,如果有多个线程同时访问和修改StringBuilder对象,可能会导致数据不一致或出现竞态条件的问题。因此,StringBuilder适用于单线程环境下对字符串的修改操作。

    //StringBuilder部分源码@Overridepublic StringBuilder append(Object obj) {return append(String.valueOf(obj));}@Overridepublic StringBuilder append(String str) {super.append(str);return this;}

三者性能分析

String:由于String是不可变的,每次对String进行修改操作时,都会创建一个新的String对象。这可能导致频繁的对象创建和垃圾回收,影响性能

StringBuilder:由于StringBuilder是可变的,它使用可变的字符数组存储字符串,不会每次都创建新的对象。在需要频繁进行字符串拼接、替换等操作时,使用StringBuilder可以提高性能

StringBuffer:与StringBuilder类似,StringBuffer也是可变的,但是它是线程安全的。在多线程环境下,由于同步机制的存在,StringBuffer的性能可能会稍低于StringBuilder

使用场景

String:适用于不需要频繁修改字符串内容的场景。由于String是不可变的,每次对String进行拼接、替换或者修改操作时,都会创建一个新的String对象,这样可能会导致频繁的对象创建和垃圾回收,影响性能。因此,如果字符串内容不需要改变,或者只需要读取字符串的值,可以使用String。

  1. 对于一些常量字符串或者字面量,例如日志输出时的提示信息、固定格式的输出等,由于它们的值是固定的,不需要做任何修改,因此可以使用String。

  2. 在某些业务逻辑中,需要对字符串进行一些操作,但这些操作的结果不会影响原始字符串。例如,从数据库中查询到的数据如果需要展示给用户,通常不会被修改,这种场景下可以使用String。

StringBuilder:适用于单线程环境下需要频繁修改字符串的场景。由于StringBuilder是可变的,它使用可变的字符数组存储字符串,不会每次都创建新的对象。因此,在需要频繁进行字符串拼接、替换等操作时,使用StringBuilder可以提高性能。

  1. 在开发Web应用时,需要将多个字符串拼接成一个完整的HTML页面,这种场景下可以使用StringBuilder。

  2. 当需要从文件中读取数据,并进行一系列复杂的字符串操作时,可以使用StringBuilder。

StringBuffer:适用于多线程环境下需要频繁修改字符串的场景。与StringBuilder类似,StringBuffer也是可变的,但是它是线程安全的,内部的方法都使用了synchronized关键字进行同步。这意味着在多线程环境下,多个线程可以安全地同时访问和修改StringBuffer对象。因此,如果在多线程环境下需要频繁进行字符串操作,应该使用StringBuffer来确保线程安全。

  1. Web服务器需要同时处理多个客户端请求,这种场景下可以使用StringBuffer来确保线程安全。

  2. 一个多线程的任务,需要将多个线程的执行结果拼接成一个完整的字符串,可以使用StringBuffer。

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

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

相关文章

【MySQL表的增删查改】

文章目录 前言1 Create1.1 单行数据 全列插入1.2 多行数据 指定列插入1.3 插入否则更新1.4 替换 2 Retrieve2.1 SELECT 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式2.1.4 为查询结果指定别名2.1.5 结果去重 2.2 WHERE 条件2.2.1 英语不及格的同学及英语成绩 ( &…

C++基础:指针数组和数组指针(大白话讲解)

指针数组&#xff1a;本质上是一个数组&#xff0c;数组中的每一个元素都是一个指针&#xff1b; 数组指针&#xff1a;本质上是一个指针&#xff0c;数组指针是一个指向数组的指针。 为了更直观的分析他们的区别&#xff0c;我举个例子&#xff1a; #include<iostream&g…

操作系统:可变分区管理

有作业序列&#xff1a;作业A要求42K&#xff1b;作业B要求27K&#xff0c;作业C要求22K&#xff0c;作业和空闲内存区如下图所示&#xff0c;请画出最佳适应算法空闲队列图&#xff0c;并分析最佳适应算法是否适合该作业系列。 答&#xff1a;最佳适应算法是按照空闲块由小到大…

【辐射场】3D Gaussian Splatting

三维高斯…喷喷 \, 3D Gaussian Splatting&#xff0c;下文简称3DGS&#xff0c;是好一段时间以来在三维内容创作和三维重建领域比较有热度的一项技术。 它属于基于图像的三维重建方法&#xff0c;意思就是你对现实物体或者场景拍照片&#xff0c;就能给你训练成一个场景模型&a…

C语言之整型提升

文章目录 1 有可能出现的问题2 产生以上问题的原因&#xff08;整型提升&#xff09;3 整型提升的过程4 整型提升示例5 总结 1 有可能出现的问题 代码如下 #include <stdio.h>int main () {int a -1;unsigned int b 1;if (a < b) {printf("a < b");}…

【Spring Security】认证之案例的使用、MD5加密、CSRF防御

目录 一、引言 1、什么是SpringSecurity认证 2、为什么使用SpringSecurity之认证 3、实现步骤 二、快速实现&#xff08;案例&#xff09; 1、添加依赖 2、配置 3、导入数据表及相关代码 4、创建登录页及首页 5、创建配置Controller 6、用户认证 6.1、用户对象User…

WEB 3D技术 three.js通过 GLTFLoader 导入并应用 gltf/glb 3D资源

上文 WEB 3D技术 three.js 雾 基础使用讲解我们讲了雾的基本使用方法 但是 如果我们要做一个树林 一颗一颗树去加 那真的是要累死了 我们一定是在建模软件上 建模好这样的模型 然后将模型导入到场景中 官网中搜索 GLTFLoader 在我们日常WEB开发中 用的最多的3D格式 就是 GLTF…

python练习2【题解///考点列出///错题改正】

一、单选题 【文件】 *1.【单选题】 ——文件&#xff1a;读取方法 下列哪个选项可以从文件中读取任意字节的内容&#xff1f;&#xff08;C &#xff09;A A.read() B.readline() C.readlines() D.以上全部 A\B\C三种方法都是可以读取文件中任意的字节内容的&#xff0…

Lesson 06 vector类(上)

C&#xff1a;渴望力量吗&#xff0c;少年&#xff1f; 文章目录 一、vector是什么&#xff1f;二、vector的使用1. 构造函数2. vector iterator3. vector 空间增长问题4. vector增删查改 三、vector实际使用 一、vector是什么&#xff1f; vector是表示可变大小数组的序列容器…

使用Python实现简单的区块链

区块链技术作为一种分布式数据库技术,近年来备受关注。它的去中心化、安全性高的特点使得它在金融、物联网、供应链管理等领域有着广泛的应用前景。本文将介绍如何使用Python语言实现一个简单的区块链,包括创建区块、交易记录和工作量证明等功能。 区块链基本概念 区块链是由…

mysql视图(view)视图、创建、使用、查询、删除、视图的作用等操作

视图 1、视图的定义2、视图的创建3、视图的使用4、视图的查询5、查看视图的建立6、删除视图7、视图的作用 1、视图的定义 视图&#xff1a;视图是从一个或者多个基本表&#xff08;或视图&#xff09;导出的表。它与基本表不同&#xff0c;是一个虚表。视图有一个特性&#xf…

LVGL 在framebuffer设备上的移植

LVGL 在framebuffer设备上的移植 ItemDescDate2023-12-31Authorhongxi.zhuplatformNXP I.MX6ULLLCDSPI TFTLCD NV3030B 文章目录 LVGL 在framebuffer设备上的移植一、LVGL源码获取二、源码修改适配三、编译&运行补充 一、LVGL源码获取 新建lvgl_imx6ull文件夹&#xff0c…

低代码开发中业务蓝图的重要性:业务需求与系统实现的桥梁

在低代码应用开发领域&#xff0c;业务蓝图是一个至关重要的工具&#xff0c;它提供了组织业务流程需求的详细信息。它类似于一份指导开发人员进行应用开发的路线图&#xff0c;确保与业务的战略目标和需求保持一致。 低代码方法学&#xff0c;顾名思义&#xff0c;即减少了传…

水利工程制图解决方案的突破

小小的纪念下&#xff0c;终于实现CAD数字成图的实现&#xff0c;在高标准农田设计中软件成图比例占比60%以上。

Google机器人团队获ICRA 2023 机器人学习方向最佳论文奖:机器人实体控制的大语言模型程序

这篇论文主要讨论了大型语言模型&#xff08;LLM&#xff09;在机器人控制方面的应用。作者们指出&#xff0c;尽管LLM在理解和生成自然语言方面表现出色&#xff0c;但其在实际应用中&#xff0c;如机器人控制等领域的应用仍然有限。因此&#xff0c;他们提出了一种新的方法&a…

力扣labuladong一刷day49天迪杰斯特拉

力扣labuladong一刷day49天迪杰斯特拉 文章目录 力扣labuladong一刷day49天迪杰斯特拉一、743. 网络延迟时间二、1631. 最小体力消耗路径三、1514. 概率最大的路径 一、743. 网络延迟时间 题目链接&#xff1a;https://leetcode.cn/problems/network-delay-time/ 使用迪杰斯特…

登峰造极,师出造化,Pytorch人工智能AI图像增强框架ControlNet绘画实践,基于Python3.10

人工智能太疯狂&#xff0c;传统劳动力和内容创作平台被AI枪毙&#xff0c;弃尸尘埃。并非空穴来风&#xff0c;也不是危言耸听&#xff0c;人工智能AI图像增强框架ControlNet正在疯狂地改写绘画艺术的发展进程&#xff0c;你问我绘画行业未来的样子&#xff1f;我只好指着Cont…

每日一题——LeetCode976

方法一 个人方法 找规律&#xff1a; 要求要围成三角形且周长最大&#xff0c;那么三条边自然是越大且越接近越好。那么我们就从最大的三条边开始看能不能围成三角形。如果不能组成三角形&#xff0c;则丢弃最长的那条&#xff0c;再取剩余边里最长的那条再看能不能组成三角形…

第二百三十八回

文章目录 1. 概念介绍2. 原因与方法2.1 问题原因2.2 解决方法 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"修改页面导航中遇到的问题"沉浸式状态样相关的内容&#xff0c;本章回中将介绍如何修改Avatar的大小.闲话休提&#xff0c;让…

二叉树的中序遍历,力扣

目录 题目地址&#xff1a; 题目&#xff1a; 解题方法&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现&#xff1a; 注&#xff1a; 代码实现&#xff08;递归&#xff09;&#xff1a; 代码实现&#xff08;迭代&#xff09;&#xff1a; 题目地址&#xf…