String、StringBuilder、StringBuffer 有什么区别?

1、典型回答

String、StringBuilder 和 StringBuffer 都是 Java 语言中,用于操作字符串的类,但它们在性能、可变性和线程安全性方面有一些区别

1、String:不可变字符串类,也就是说一旦创建,它的值就不可变。每次对 String 进行拼接、裁剪等操作时,都会创建一个新的 String 对象,所以它的这些操作效率不高,但由于其不可变性,String 可以保证线程安全,适用于字符串不经常变化的场景

2、StringBuffer:线程安全的可变字符串类,它解决了 String 字符串拼接、裁剪的问题,它提供了对字符串进行操作的 append 和 insert 等方法,可以将字符串添加到末尾或指定位置,并且它不会创建新字符串。并且 StringBuffer 是线程安全的,适用于多线程环境下对字符串的操作,其诞生于 JDK1.0

3、StringBuilder:非线程安全的可变字符串类,与StringBuffer 类似,但是它去掉了线程安全的部分,有效减小了开销,是绝大部分情况下进行字符串拼接的首选,它诞生于JDK1.5

2、全面剖析

将 String 设计为不可变的,可以更好用于缓存、保证线程安全、并提高程序的性能,但它的副作用就是在字符串拼接和裁剪的时候总要创建新字符串,性能不高,因此字符串变化的场景中要使用 StringBuffer 来替代,但 StringBuffer 底层使用了 synchronized 修饰在 append 等拼接方法上,如下源码所示:

所以,StringBuffer 效率也不是很高,于是在 JDK 1.5 的时候就有了去掉锁,但功能和 StringBuffer 完全相同的 StringBuilder 

3、知识扩展

关于字符串还有几个问题比较重要:

  1. StringBuffer 和 StringBuilder 有什么关系?它们的底层是如何实现的?
  2. intern() 方法的作用是啥?为什么要用 intern() 方法?它有什么副作用么?

3.1、StringBuilder 和 StringBuffer 底层实现

属于 “亲兄弟”的关系,因为它们都继承了同一个类 AbstractStringBuilder ,如下图所示:

String 的底层是使用数组实现的,而 StringBuilder 和 StringBuffer 的底层也是使用数组实现的,只是 StringBuilder 和 StringBuffer 的数组并未加 final 修饰,实现源码如下:

3.2、intern 方法说明

String 的 intern() 方法用于将字符串添加到字符串常量池中,并返回常量池中对应的字符串对象的引用

常量池是Java 运行时环境中的一个特殊存储区域,用于存储在编译期间确定的字符串常量和符号引用。当调用String的 intern() 方法时,如果常量池中已经存在相同值的字符串,则返回对应的引用;如果常量池中不存在,则在常量池中创建并返回对应的引用

例如以下代码:

String 创建对象的方式中,直接字符串赋值也就是 str1 的方式会默认将在常量池中创建对象,而new 对象的方式也就是str2的方式则是在堆上创建的

intern 方法的副作用主要有以下两个:

  1. 代码中大量使用 intern 方法会使得代码臃肿,且不易维护
  2. 使用 intern 方法会增加方法区的内存占用,而老版本的方法区是存储在永久代中的(JDK1.7之前),而永久代的空间又很小,因此如果 intern 方法使用不当,就会导致频频进行垃圾回收,所以在老版本要慎用 intern 方法 

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

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

相关文章

Spring boot 集成netty实现websocket通信

一、netty介绍 Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和U…

Loader、source

Loader 是在 QML 中用于动态加载和创建其他 QML 文件或组件的元素。它允许您根据需要在运行时加载和实例化其他的 QML 文件,以实现动态性和灵活性。 以下是一个简单的示例,展示了如何在 QML 中使用 Loader: Loader {sourceComponent: MyCom…

数码管的动态显示(二)

1.原理 这个十六进制是右边的dp为高位。 数码管的动态显示,在第一个计数周期显示个位,在第二个周期显示十位,在第三个周期显示百位由于人眼的视觉和数码管的特性,感觉就是显示了234,每个数码管的显示需要从输入的数据里…

Go语言必知必会100问题-23 判断空切片最佳方法

前言 在Go语言必知必会100问题-22 空切片与nil切片有区别吗?中分析了空切片和nil切片是有区别的,那如何正确的判断一个切片是否为空切片呢? 案例引入 下面通过一个具体的例子进行说明,getOperations 函数返回一个float32类型的…

Flutter第四弹:Flutter图形渲染性能

目标: 1)Flutter图形渲染性能能够媲美原生? 2)Flutter性能优于React Native? 一、Flutter图形渲染原理 1.1 Flutter图形渲染原理 Flutter直接调用Skia。 Flutter不使用WebView,也不使用操作系统的原生控件,而是…

Java学习笔记14——常量与变量

曾和儿子分享过所谓计算机程序,都是编写代码进行“数据处理和处理数据”而已。任何编程语言编写何种应用,数据都必须以某种方式表示。掌握变量和常量的用法,可以使代码的可维护性、可读性大大提高。 一、常量 常量就是在程序中固定不变的量…

C语言scandir函数获取文件夹内容

scandir 函数用于列举指定目录下的文件列表,并将结果存储在一个动态分配的数组中。 函数原型: int scandir(const char *dirpath, struct dirent ***namelist,int (*filter)(const struct dirent *),int (*compar)(const struct dirent **, const stru…

labview中6种机械动作的区别

1.单击时转换:单击时转换,需要手动转换或者赋值回复原来状态; 2.释放时转换:释放时时转换,需要手动转换或者赋值回复原来状态; 3.单击时转换保持到鼠标释放:触发两次,自动恢复原来状…

Python互斥锁实例(包含超时解锁)

Python互斥锁实例(包含超时解锁) 文章目录 前言正文1 锁被占用直接返回2 拿不到锁则一直等待3 拿不到锁等待直到超时 总结 前言 最近遇到一个小需求,大概是请求机器人&自动化设备执行某些功能,这些功能之间有共同操作资源或在…

Linux:导出环境变量命令export

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 Linux中的内建命令export命令用于创建一个环境变量,或将一个普通变量导出为环境变量,并且在这个过程中,可以给该环境变量赋值。 下面…

多数问题求解之蒙特卡洛与分治法

多数问题(Majority Problem)是一个有多种求解方法的经典问题,其问题定义如下: 给定一个大小为 n n n的数组,找出其中出现次数超过 n / 2 n/2 n/2的元素 例如:当输入数组为 [ 5 , 3 , 5 , 2 , 3 , 5 , 5 ] […

【WPS】压缩图片

第一步: 点击插入,点击图片 第二步: 点击图片工具,点击压缩图片 第三步:

Vue3 前端生成随机id( 生成 UUID )

效果展示 封装工具(代码展示) 重新创建一个文件**/utils/someTools.js**,并在里面写入如下代码。 function Tools() {}Tools.prototype.guid function () {return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g, function (c) {v…

jQuery模态框弹窗提示代码

jQuery模态框弹窗提示代码 下载地址 jQuery模态框弹窗提示代码

GPT每日面试题—Vue中style的scoped是如何实现样式隔离的

充分利用ChatGPT的优势,帮助我们快速准备前端面试。今日问题:Vue中style的scoped是如何实现样式隔离的。 Q:在前端面试中,如果被问到,vue文件中的scoped是如何实现样式格式的,什么回答比较好,全…

Requests教程-17-请求代理设置

上一小节我们学习了requests解决乱码的方法,本小节我们讲解一下requests设置代理的方法。 代理基本原理 代理实际上指的就是代理服务器, 英文叫作proxy server ,它的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中…

【阿里云系列】-基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户,我们通常会选择CICD工具来减少人力投入产生的成本,开源的工具比如有成熟的Jenkins,但是本文讲的是阿里云提高的解决方案云效平台,通过配置流水线的形式实现项目的快速部署到服务器…

【数据结构】双向链表及LRU缓存的实现

目录 前言 1. 在原有的自定义链表类 Linked 的基础上,添加新的 “节点添加”方法 addNode(Node node) 测试用例 测试结果 2. 在自定义链表类的基础上,使用双重循环“强力” 判断两个节点是否发生相交 测试用例 测试结果 3. 在自定义链表类的基础上…

突破编程_C++_面试(STL 编程 list)

面试题 1 :描述 std::list 的内部数据结构是什么,以及它如何影响性能? std::list 的内部数据结构是一个双向链表。这意味着它是由一系列节点组成的,每个节点都包含两部分:一部分是存储实际数据的数据域,另…

每日OJ题_哈希表⑤_力扣49. 字母异位词分组

目录 力扣49. 字母异位词分组 解析代码 力扣49. 字母异位词分组 49. 字母异位词分组 难度 中等 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入…