Java 字符串 String、StringBulider和StringBuffer

2024-02-09 08:10

本文主要是介绍Java 字符串 String、StringBulider和StringBuffer,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、可变和不可变对象
    • 1、String
    • 2、StringBuffer和StringBuilder
  • 二、不可变对象的好处

一、可变和不可变对象

可变对象:当您拥有对对象实例的引用时,该实例的内容可以更改
不可变对象:当您拥有对对象实例的引用时,该实例的内容无法更改

使用java.lang.String作为不可变类,使用java.awt.Point作为可变类

public class StringTest {public static void main(String[] args) {Point myPoint = new Point( 0, 0 );System.out.println( myPoint );myPoint.setLocation( 1.0, 0.0 );System.out.println( myPoint );String myString = new String( "old String" );System.out.println( myString );myString.replaceAll( "old", "new" );System.out.println( myString );}
}

结果输出如下

java.awt.Point[x=0,y=0]
java.awt.Point[x=1,y=0]
old String
old String

我们只查看每个对象的单个实例,但是可以看到myPoint的内容发生了变化,而myString的内容没有发生变化。
某些语言,例如 C++ 和Ruby,通常允许在创建字符串后更改其内容;这些被称为可变字符串。在其他语言中,例如Java和Python,该值是固定的,如果要进行任何更改,则必须创建一个新字符串;这些被称为不可变字符串(其中一些语言还提供了另一种可变类型,例如 Java 和.NET StringBuilder、线程安全的 JavaStringBuffer和Cocoa NSMutableString)。

1、String

在 Java 编程中广泛使用的字符串是一个字符序列。在 Java 编程语言中,字符串是对象。

通过查看String.java的源码可以知道String是被final修饰的,因此它是不能被继承的。

public final class String {
}

下面我们来看一组代码

public class StringTest {public static void main(String[] args) {String str1 = "hello";String str2 = "hello";System.out.println(str1 == str2);}
}

下面是该代码的内存图
在这里插入图片描述
凡是带有双引号的字符串都会放在字符串常量池中,字符串放在字符串常量池是为了提高效率。如果使用构造函数或方法创建字符串,则这些字符串将存储在堆内存中的SringConstantPool,但是在保存到池中之前,它会调用intern()方法来使用 equals()方法检查池中具有相同内容的对象可用性。如果池中的字符串副本可用,则返回引用。否则,将 String 对象添加到池中并返回引用。

再来看一组代码

public class StringTest {public static void main(String[] args) {String str3 = new String("abcde");String str4 = new String("abcde");System.out.println(str3 == str4);}
}

此时 str3 和 str4 都在堆中创建了对象,这两个对象时两个不同地址的空间,所以上述代码的结果为false。但是他们所指引的字符串还是在字符串常量区中。
在这里插入图片描述
下面我们再来看一组代码,以下代码会创建十一个对象。假如,我们for循环执行上万条,此时,会造成字符串常量区溢出,所以这个时候就不适合在循环里使用连接符操作字符串。这时就出现了StringBuffStringBuilder

String str = "a";
for (int i = 0; i < 10; i++) {str += "b";
}
System.out.println(str);

在这里插入图片描述

2、StringBuffer和StringBuilder

String是一个不可变的类,无法改变。StringBuilder是一个可变类,可以附加到替换或删除的字符,最终转换为String

下面是常用的方法

public class StringTest {public static void main(String[] args) {StringBuilder sb = new StringBuilder();String str = "java";// 将字符串添加"xiao"字符串sb.append("xiao");// 将sb字符串中第 [0, 2) 位字符替换为str -- javaaosb.replace(0, 2, str);// 删除第 [3, 5) 为字符                -- javosb.delete(3, 5);// 返回字符串的长度                     -- 4System.out.println(sb.length());// 返回指定下标的值                     -- jSystem.out.println(sb.charAt(0));// 返回下标为 [0, 3) 之间的子序列        -- javSystem.out.println(sb.substring(0, 3));System.out.println(sb);}
}

StringBuffer 每当我们对使用此类创建的任何 String 进行一些更改时,都不会创建新对象,因为更改是在同一对象中进行的。这个类是线程安全的,即它可以在多线程环境中正常工作。此类的方法是同步的,因此每当多个线程调用对象上的某些方法时,它们就会按照每个单独线程进行的方法调用的顺序执行。
常用方法:

  • append – 在字符串的末尾追加数据。
  • insert – 在任何给定索引处插入数据。

StringBuilder 这是 StringBuffer 类的一个新的但更小的版本,随着 JDK 5 的发布而引入。它与 StringBuffer 类似,但它不为线程安全或同步提供任何保证。
它用于只有一个线程应用程序的地方,因为它在大多数情况下要快得多。其余部分与 StringBuffer 类似,具有相同的方法和声明。我们只需要在初始化期间使用不同的类,其余的代码不需要更改,因为它也有相同的方法。

下面是三者的区别
在这里插入图片描述

二、不可变对象的好处

  • 默认情况下,不可变对象是线程安全的,可以在并发环境中共享而无需同步。
  • 不可变对象简化了开发,因为它更容易在多个线程之间共享,而无需外部同步。
    -通过减少代码中的同步,java应用程序的不可变对象提升性能。
  • 不可变对象的另一个重要优点是可重用性,您可以缓存不可变对象并重用它们,就像字符串文本和整数一样。您可以使用静态工厂方法来提供valueOf()之类的方法,它可以从缓存返回现有的不可变对象,而不是创建新对象。

来看下他们三个的使用场景

  1. 如果不是在循环体中进行字符串拼接的话,直接使用 String 的 “+” 就好了。

  2. 单线程循环中操作大量字符串数据 → StringBuilder.append()

  3. 多线程循环中操作大量字符串数据 → StringBuffer.append()

这篇关于Java 字符串 String、StringBulider和StringBuffer的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/693652

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (