首页 > 其他分享 >String、StringBuffer和StringBuilder的区别

String、StringBuffer和StringBuilder的区别

时间:2024-10-31 18:32:41浏览次数:1  
标签:String StringBuffer 线程 StringBuilder 字符串 final

String、StringBuffer和StringBuilder的区别

  下面从可变性、是否线程安全等方面来对String、StringBuffer、StringBuilder进行比较。

   一、可变性

   1. String

   String 类中使用 final 关键字修饰字符数组来保存字符串。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
  //...
}

   分析:我们知道被 final 关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本数据类型则值不能改变,修饰的变量是引用类型则不能再指向其他对象。因此,final 关键字修饰的数组保存字符串并不是 String 不可变的根本原因,因为这个数组保存的字符串是可变的(final 修饰引用类型变量的情况)。

   String 真正不可变有下面几点原因:

   1)保存字符串的数组被 final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法。

   2)String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变。

   2. StringBuffer

   StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰,最关键的是这个 AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。

 

  二、线程是否安全

  1.  String

  String在Java中是线程安全的。

  原因:

  1)不可变性:一旦创建,String 对象的内容就不能更改。

  2)内存管理:Java 使用字符串常量池来优化内存使用。当多个 String 对象具有相同的值时,它们实际上会引用同一个对象。

在多线程环境中,多个线程可以安全地读取同一个 String 对象而无需同步。由于不可变性,不需要额外的同步机制来保护 String 对象,因此可以提高性能。

  2. StringBuilder

  StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

  3. StringBuffer

  StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁(synchronized), 所以是线程安全的。这意味着在多线程环境中,StringBuffer 可以安全地被多个线程访问。

  部分源码如下:

 1 public final class StringBuffer extends AbstractStringBuilder implements Serializable, CharSequence
 2 {
 3     //...
 4     @Override
 5     public synchronized StringBuffer append(Object obj) {
 6         toStringCache = null;
 7         super.append(String.valueOf(obj));
 8         return this;
 9     }
10 }

    三、是否实现了equals和hashCode方法

    1. String

    String 类重写了 equals() 和 hashCode() 方法,使得两个 String 对象可以根据其内容进行比较。例如:

 1 public class StringExample {
 2     public static void main(String[] args) {
 3         String str1 = new String("java");
 4         String str2 = new String("java");
 5         
 6         // 比较两个 String 对象的内容
 7         System.out.println(str1.equals(str2)); // 输出: true
 8         System.out.println(str1.hashCode() == str2.hashCode()); // 输出: true
 9     }
10 }

 

 StringBuilder 和 StringBuffer 没有实现 equals() 和 hashCode() 方法,使用时主要关注字符串的构建和修改。
如果需要比较内容,可以使用 toString() 方法将其转换为 String,然后进行比较。

 

    总结:

 

String:不可变,适合不频繁修改的字符串,性能较低。
StringBuffer:可变,线程安全,适合多线程环境,性能较好。
StringBuilder:可变,非线程安全,性能最好,适合单线程环境。通常在需要频繁修改字符串时优先选择。

 


4. 字符串拼接用“+” 还是 StringBuilder?

Java 语言本身并不支持运算符重载,“+”和“+=”是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的运算符。

4. 总结:

我们在平时写代码的时候,尽量避免多个字符串对象拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer。不过,字符串使用 final 关键字声明之后,可以让编译器当做常量来处理。


原文链接:https://javaguide.cn/java/basis/java-basic-questions-02.html

标签:String,StringBuffer,线程,StringBuilder,字符串,final
From: https://www.cnblogs.com/hld123/p/18518614

相关文章

  • string类的深度剖析1
    文章目录1.前置语法知识——auto和范围for1.1auto关键字1.2范围for2.string类2.1为什么要学string类2.2认识string类2.3string类的常用接口说明2.3.1常见构造2.3.2容量操作2.3.3访问及遍历操作2.3.4修改操作2.3.5非成员函数3.结尾1.前置语法知识——au......
  • C++(std::to_string())
    目录1.函数定义2.示例代码3.内部实现机制4.注意事项5.应用场景6.使用std::ostringstream控制精度的示例7.总结std::to_string()是C++11引入的一个标准库函数,用于将基本数据类型(如整数、浮点数等)转换为对应的字符串格式。这个函数属于<string>头文件,因此使用时需......
  • c++ string 识别标志位并解析标志位后面的字符
    解析字符串中的固定标志位正则表达式和iterator的配合应用#include<string>#include<map>#include<regex>#include<iostream>//替换\\M+后面的字符//\\M+195B6替换为文std::regexpattern(R"(\\M+[^\\M]*)");//匹配\\M+后跟任意非\\M的字符(0次或多次)......
  • 管中窥豹----从String Intern中观察.NET Core到.NET 8 托管堆的变迁
    简介https://www.cnblogs.com/lmy5215006/p/18494483在研究.NETString底层结构时,我所观察到的情况与《.NETCore底层入门》,《.NET内存管理宝典》书中描述不符。故多研究了一下。发现.NET托管堆的结构也是越来越多,越来越高性能。 //示例代码internalclassProgram{......
  • Array and string offset access syntax with curly braces is deprecated
    你遇到的这个问题确实是因为PHP版本升级后对一些语法的支持发生了变化。具体来说,从PHP7.4开始,使用大括号 {} 访问数组和字符串的偏移已经被弃用,并将在未来的版本中完全移除。因此,你需要对代码进行相应的调整。解决方法方法一:降级PHP版本更改PHP版本为7.0以下的版本:如果你......
  • 【C++】string 类深度解析:探秘字符串操作的核心
     快来参与讨论......
  • How to use js to parse a url string to a url object All In One
    HowtousejstoparseaurlstringtoaurlobjectAllInOne如何利用js将url字符串解析为url对象demos//consturl=globalThis.window.location.href;//consturl=window.location.href;constautoConvertPageToRepo=(page=``)=>{if(!globalThis.wi......
  • [LeetCode] 3216. Lexicographically Smallest String After a Swap
    Givenastringscontainingonlydigits,returnthelexicographicallysmalleststringthatcanbeobtainedafterswappingadjacentdigitsinswiththesameparityatmostonce.Digitshavethesameparityifbothareoddorbothareeven.Forexample,5......
  • string和初学指针和动态内存分配
    strcmp:原型定义于:<string.h>intstrcmp(constchar*str1,constchar* str2)比较的标准是ASCII从第一个字符开始比,直到遇到不同的字符或者返回NULL(0)若STR1[I]>STR2[I],返回1若STR1[I]<STR2[I],返回-1若STR1[I]=STR2[I],返回0strcpy:原型定义于<string.h>常用于字符串......
  • 【JavaSE】认识String类,了解,进阶到熟练掌握
    #1024程序员节|征文#下面就让博主带领大家一起解决心中关于String类的疑问吧~~~1.字符串构造:第一种和第二种(有一定的区别,在常量池上)publicstaticvoidmain(String[]args){//使用常量串构造Strings1="hello";System.out.println(s1);//直接newString对象S......