String 和 StringBuffer和 StringBuilder 场景应用

目录

  • 1.三者区分
  • 2.String 不可变性的示例代码:
  • 3.String 频繁创建对象
  • 4.StringBuffer 是可变的,可以进行增删改操作而不产生新的对象。
  • 5.StringBuffer 是线程安全的,适合在多线程环境下使用,但同步会带来一定的性能损耗。 代码举例
  • 6.StringBuilder 也是可变的,与 StringBuffer 类似,但不是线程安全的。在单线程环境下,StringBuilder 的性能比 StringBuffer 更好。 代码举例
  • 7.各自应用场景

1.三者区分

String、StringBuffer 和 StringBuilder 都是 Java 中用于处理字符串的类,它们之间有一些重要的区别。

  1. String:

    • String 对象是不可变的,一旦创建就不能被修改。每次对 String 对象进行操作(连接、截取、替换等)都会创建一个新的 String 对象。
    • 这种不可变性使得 String 对象在多线程环境下更安全,但是如果需要频繁地进行字符串操作,会产生大量的临时对象,影响性能。
  2. StringBuffer:

    • StringBuffer 是可变的,可以进行增删改操作而不产生新的对象。
    • StringBuffer 是线程安全的,适合在多线程环境下使用,但同步会带来一定的性能损耗。
  3. StringBuilder:

    • StringBuilder 也是可变的,与 StringBuffer 类似,但不是线程安全的。在单线程环境下,StringBuilder 的性能比 StringBuffer 更好。

选择使用场景:

  • 如果在单线程环境下进行大量字符串操作,并且不需要线程安全性,推荐使用 StringBuilder。
  • 如果在多线程环境下进行字符串操作,或者需要线程安全性,应该使用 StringBuffer。
  • 如果字符串基本不需要修改,或者只进行少量的操作,可以使用 String。

2.String 不可变性的示例代码:

String 对象是不可变的,一旦创建就不能被修改。每次对 String 对象进行操作(连接、截取、替换等)都会创建一个新的 String 对象。 代码举例

String s1 = "Hello";
String s2 = s1 + ", World!";
String s3 = s2.substring(7);System.out.println(s1); // 输出 "Hello"
System.out.println(s2); // 输出 "Hello, World!"
System.out.println(s3); // 输出 "World!"System.out.println(s1 == "Hello"); // 输出 true
System.out.println(s2 == "Hello, World!"); // 输出 false
System.out.println(s3 == "World!"); // 输出 false

在这个示例中,我们首先定义了一个字符串 s1,然后将其与另一个字符串 "Hello, World!" 进行连接,生成一个新的字符串 s2。接着,我们从 s2 中截取了一个子字符串,得到 s3

需要注意的是,虽然我们对 s2s3 进行了操作,但是 s1 的值不会发生改变,因为 String 对象是不可变的。每次对 String 对象进行操作都会生成一个新的 String 对象,原来的对象不会被修改。

此外,在比较字符串是否相等时,不能使用 == 运算符,应该使用 equals() 方法进行比较。因为 == 运算符比较的是对象的引用,而 equals() 方法比较的是对象的内容。在上面的示例中,s1"Hello" 在内存中是同一个对象,因此 s1 == "Hello" 返回 true。而 s2"Hello, World!" 不是同一个对象,因此 s2 == "Hello, World!" 返回 false。

3.String 频繁创建对象

这种不可变性使得 String 对象在多线程环境下更安全,但是如果需要频繁地进行字符串操作,会产生大量的临时对象,影响性能。 代码举例
以下是一个简单的示例,演示在频繁进行字符串操作时会产生大量临时对象:

public class StringPerformanceExample {public static void main(String[] args) {long startTime = System.nanoTime();String result = "";for (int i = 0; i < 10000; i++) {result += "hello"; // 每次循环都会创建一个新的 String 对象}long endTime = System.nanoTime();long duration = (endTime - startTime) / 1000000; // 将纳秒转换为毫秒System.out.println("Duration: " + duration + " ms");}
}

在这个示例中,我们用一个循环将字符串 “hello” 连接了 10000 次,每次循环都会创建一个新的 String 对象。由于 String 对象的不可变性,每次连接操作都会产生一个新的 String 对象,这样就产生了大量的临时对象。

当我们运行上述代码时,会发现花费的时间相对较长,这是因为频繁地创建临时对象会导致额外的内存开销和垃圾回收压力,从而影响性能。

为了避免这种情况,可以使用 StringBuilder 或 StringBuffer 类来代替频繁操作字符串,因为它们是可变的,可以有效减少临时对象的创建和提高性能。

4.StringBuffer 是可变的,可以进行增删改操作而不产生新的对象。

下面是使用 StringBuffer 进行字符串操作的示例代码:

public class StringBufferExample {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("Hello");System.out.println("Original: " + stringBuffer); // 输出 "Hello"// 追加字符串stringBuffer.append(", World!");System.out.println("After append: " + stringBuffer); // 输出 "Hello, World!" // 插入字符串stringBuffer.insert(5, "Beautiful ");System.out.println("After insert: " + stringBuffer); // 输出 "Hello, Beautiful World!"// 替换字符串stringBuffer.replace(6, 15, "Wonderful");System.out.println("After replace: " + stringBuffer); // 输出 "Hello, Wonderful World!"// 删除字符串stringBuffer.delete(6, 16);System.out.println("After delete: " + stringBuffer); // 输出 "Hello, World!"}
}

在这个示例中,我们首先创建了一个 StringBuffer 对象,并对其进行了追加、插入、替换和删除操作。由于 StringBuffer 是可变的,这些操作都是在原对象上进行的,不会创建新的对象。因此,使用 StringBuffer 可以有效避免频繁创建临时对象的问题,提高性能。

5.StringBuffer 是线程安全的,适合在多线程环境下使用,但同步会带来一定的性能损耗。 代码举例

下面是一个使用 StringBuffer 在多线程环境下进行字符串操作的示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class StringBufferThreadExample {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer();ExecutorService executorService = Executors.newFixedThreadPool(3);for (int i = 0; i < 3; i++) {executorService.execute(() -> {for (int j = 0; j < 10000; j++) {stringBuffer.append("hello"); // 追加字符串操作}});}// 关闭线程池executorService.shutdown();while (!executorService.isTerminated()) {// 等待所有任务完成}System.out.println("Result: " + stringBuffer.length()); // 输出 30000}
}

在这个示例中,我们创建了一个 StringBuffer 对象,并使用线程池执行了 3 个线程,每个线程都会将字符串 “hello” 追加到 StringBuffer 中。由于 StringBuffer 是线程安全的,多个线程同时对其进行操作不会导致数据不一致的问题。

需要注意的是,在多线程环境下使用 StringBuffer 需要考虑同步的性能损耗。由于 StringBuffer 的方法都是 synchronized 的,会引入额外的同步开销,可能会影响性能。如果不需要线程安全的操作,可以考虑使用 StringBuilder 类,它与 StringBuffer 类相似,但不提供同步机制,因此在单线程环境下性能更好。

6.StringBuilder 也是可变的,与 StringBuffer 类似,但不是线程安全的。在单线程环境下,StringBuilder 的性能比 StringBuffer 更好。 代码举例

下面是使用 StringBuilder 进行字符串操作的示例代码:

public class StringBuilderExample {public static void main(String[] args) {StringBuilder stringBuilder = new StringBuilder("Hello");System.out.println("Original: " + stringBuilder); // 输出 "Hello"// 追加字符串stringBuilder.append(", World!");System.out.println("After append: " + stringBuilder); // 输出 "Hello, World!"// 插入字符串stringBuilder.insert(5, "Beautiful ");System.out.println("After insert: " + stringBuilder); // 输出 "Hello, Beautiful World!"// 替换字符串stringBuilder.replace(6, 15, "Wonderful");System.out.println("After replace: " + stringBuilder); // 输出 "Hello, Wonderful World!"// 删除字符串stringBuilder.delete(6, 16);System.out.println("After delete: " + stringBuilder); // 输出 "Hello, World!"}
}

与 StringBuffer 类似,StringBuilder 也是可变的,可以进行字符串的追加、插入、替换和删除操作。不同的是,StringBuilder 不提供同步机制,并且在单线程环境下具有更好的性能。

因为没有同步开销,StringBuilder 的操作更快,适合在单线程环境下使用。如果不需要考虑线程安全问题,建议使用 StringBuilder 来执行字符串操作以提高性能。

7.各自应用场景

String、StringBuffer 和 StringBuilder 在 Java 中都用于处理字符串,它们各自的设计背景和主要应用场景如下:

  1. String固定变量:

    • String 是 Java 中的字符串类,使用不可变的字符序列来表示字符串。这意味着一旦创建了 String 对象,它的值就不能被修改。
    • 设计背景:String 类的不可变性使得它在多线程环境下是安全的,可以被共享和重用,这在并发编程中具有优势。
    • 应用场景:适合表示不经常变化的字符串,例如常量字符串、配置信息等。
  2. StringBuffer多线程环境:

    • StringBuffer 也是用于表示字符串的类,与 String 不同的是,它是可变的,允许对字符串进行修改。
    • 设计背景:StringBuffer 被设计为线程安全的,它的方法都是使用 synchronized 关键字进行同步的,因此适合在多线程环境下使用。
    • 应用场景:适合在多线程环境下进行字符串操作的场景,但同步会带来一定的性能损耗。
  3. StringBuilder单线程环境:

    • StringBuilder 也是可变的字符串类,与 StringBuffer 类似,但不提供同步机制,因此在单线程环境下性能更好。
    • 设计背景:StringBuilder 的设计目的是提供与 StringBuffer 类似的功能,但在单线程环境下具有更好的性能,因为它不需要同步开销。
    • 应用场景:适合在单线程环境下进行字符串操作的场景,当不需要考虑线程安全问题时,可以使用 StringBuilder 来提高性能。

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

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

相关文章

聚类分析 | Matlab实现基于谱聚类(Spectral Cluster)的数据聚类可视化

聚类分析 | Matlab实现基于谱聚类(Spectral Cluster)的数据聚类可视化 目录 聚类分析 | Matlab实现基于谱聚类(Spectral Cluster)的数据聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于谱聚类(Spectral Cluster)的聚类算法可视化&#xff08;完…

融云 Global IM UIKit

GlobalIM UIKit 基于多年领先的行业经验&#xff0c;我们为开发者提供功能完备的单群聊 通信能力。“分钟级”接入&#xff0c;即可得到符合海外用户使用习惯的多端同步产品。 核心功能包括&#xff1a;快速接入、功能齐全、全球化交互体验、内容审核、灵活可配置、高度自定义、…

c++详解栈

一.什么是栈 堆栈又名栈&#xff08;stack&#xff09;&#xff0c;它是一种运算受限的数据结构&#xff08;线性表&#xff09;&#xff0c;只不过他和数组不同&#xff0c;数组我们可以想象成一个装巧克力的盒子&#xff0c;你想拿一块巧克力&#xff0c;不需要改变其他巧克…

基于AWS Serverless的Glue服务进行ETL(提取、转换和加载)数据分析(二)——数据清洗、转换

2 数据清洗、转换 此实验使用S3作为数据源 ETL: E extract 输入 T transform 转换 L load 输出 大纲 2 数据清洗、转换2.1 架构图2.2 数据清洗2.3 编辑脚本2.3.1 连接数据源&#xff08;s3&#xff09;2.3.2. 数据结构转换2.3.2 数据结构拆分…

FFmpeg开发笔记(六)如何访问Github下载FFmpeg源码

学习FFmpeg的时候&#xff0c;经常要到GitHub下载各种开源代码&#xff0c;比如FFmpeg的源码页面位于https://github.com/FFmpeg/FFmpeg。然而国内访问GitHub很不稳定&#xff0c;经常打不开该网站&#xff0c;比如在命令行执行下面的ping命令。 ping github.com 上面的ping结…

初识Linux:权限(1)

目录 提示&#xff1a;以下指令均在Xshell 7 中进行 Linux 的权限 内核&#xff1a; 查看操作系统版本 查看cpu信息 查看内存信息 外部程序&#xff1a; 用户&#xff1a; 普通用户变为超级用户&#xff1a; su 和 su-的区别&#xff1a; root用户变成普通用户&#…

KALI LINUX信息收集

预计更新 第一章 入门 1.1 什么是Kali Linux&#xff1f; 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 …

什么是SSL证书?

当我们网上购物或银行业务时&#xff0c;为了安全起见&#xff0c;我们希望看到网站的地址栏上有“HTTPS”和安全锁图标。但是这个“HTTPS”和锁定图标实际上意味着什么&#xff1f;要回答这些问题&#xff0c;我们需要了解 HTTPS、SSL 协议和 SSL 证书。 关于HTTPS、SSL和SSL…

风控反欺诈安全学习路标

1. 金融和支付领域知识 - 了解金融和支付领域的基本概念、业务流程和风险特点。 - 学习金融机构的监管要求和合规措施&#xff0c;如KYC&#xff08;了解你的客户&#xff09;和AML&#xff08;反洗钱&#xff09;。 2. 数据分析和挖掘技术 - 学习数据分析和数据挖掘的基本原理…

fastadmin获取关联表数据select渲染

php public function piliangadd(){if (false === $this->request->isPost()) {$fenlei_list = Db::name(fenlei)->order(weigh desc)->select();$this</

每天五分钟计算机视觉:稠密连接网络(DenseNet)

本文重点 在前面的课程中我们学习了残差网络ResNet,而DenseNet可以看成是ResNet的后续,我们看一下图就可以看出二者的主要区别了。 特点 DenseNet是一种卷积神经网络,它的特点是每一层都直接连接到所有后续层。这意味着,每一层都接收来自前一层的输出,并将其作为输入传递…

Flyway——Oracle创建前缀索引

文章目录 前言创建一般索引的语法前缀索引 前言 索引有助于提升数据库表的查询速率&#xff0c;极大的缩减查询的时间。但索引的创建需要考虑的因素很多&#xff0c;并非索引越多越好&#xff01; 创建一般索引的语法 oracle创建一般的常见索引&#xff0c;语法如下所示&…

n个人排成一圈,数数123离队

#include<stdio.h> int main() { int i, n100,k0,j0,a[1000]{0};//k&#xff1a;数数123的变量&#xff0c;j记录离开队列人数的变量scanf("%d",&n);for(int ii0; ii<n; ii){ for( i0; i<n; i){// printf("wei%d ",i);if((a[i]0)&&…

掌握Line多开技术,打造私人专属空间

掌握Line多开技术&#xff0c;打造私人专属空间 在现代社交网络的时代&#xff0c;人们经常需要同时处理多个社交账号&#xff0c;例如工作、家庭、朋友等不同领域的社交关系。而对于Line这样的主流社交应用来说&#xff0c;多开技术可以让用户更便捷地管理多个账号&#xff0…

数据结构线性表-栈和队列的实现

1. 栈(Stack) 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 …

Vue学习计划-Vue2--Vue核心(三)methods和computed

Vue 1. 事件 v-on 基础 使用 v-on:xxx或者xxx绑定事件&#xff0c;其中xxx是事件名 事件的回调需要配置在methods对象中&#xff0c;最终会在vm上 methods中配置函数&#xff0c;不要用箭头函数&#xff0c;否则this就不是vm了 methods中配置函数&#xff0c;都是被Vue管…

Seata使用

本文以seata-server-1.5.2&#xff0c;以配置中心、注册中心使用Nacos&#xff0c;store.modedb&#xff08;mysql&#xff09;为例进行操作。 一、Seata Server端 1、下载seata server 链接: http://seata.io/zh-cn/blog/download.html下载压缩包&#xff0c;解压至非中文目录…

Java技术栈 —— 微服务框架Spring Cloud —— Ruoyi-Cloud 学习(一)

Ruoyi-cloud 项目学习 一、项目环境搭建与启动1.1 nacos安装部署1.1.1 nacos安装、启动1.1.2 nacos部署 1.2 seata安装部署1.3 后端部署与运行1.3.1 ruoyi-modules-file模块运行报错 1.4 nginx安装、部署、配置与启动1.5 redis安装与部署1.6 前段框架知识1.7 项目启动1.8 参考 …

实用方法 | 搭建真正满足用户需求的在线帮助中心

随着互联网的普及和信息技术的快速发展&#xff0c;客户服务和支持变得越来越重要。为了提高客户满意度和维持良好的品牌形象&#xff0c;越来越多企业都开始搭建自己的在线帮助中心。 不知从何下手&#xff1f;细想一下&#xff0c;搭建在线帮助中心主要就是为了解决用户的问…

根据java类名找出当前是哪个Excel中的sheet

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …