String、StringBuilder、StringBuffer区别和关系

本文深入探讨Java中String、StringBuilder和StringBuffer的特性与差异,解析字符串常量池的作用,以及各种字符串操作方法,如拼接、比较、替换等,并对比了不同字符串类在多线程环境下的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String:它是一个最终的类(final),所以在多线程中使用是安全的,我们不需要做任何其他同步操作。String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享(在java中功效远高于提取和拼接字符串)。它不提供修改字符串的方法。

1)检测字符串是否相等:使用equals方法(区分大小写)和equalsIgnoreCase(不区分大小写)

2)==是检测字符串是否存储在同一个位置。

常见面试题:

a)此处str1返回的是常量池中的对象,str2返回的是堆中的对象(总共创建一个对象),如果先是有str2再有str1时,str2创建了两个对象(一个在堆中一个在常量池中),str1不创建对象,而是返回的是str2常量池中的对象。

String str1="abc"; 
String str2=new String("abc"); 
System.out.println(str1==str2);//false

b)首先介绍一下字符串常量池,JVM为了避免频繁的创建和销毁对象而影响系统性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串常量池。他的本质其实就是一个Hash表,在JDK7之前字符串常量池位于JVM的方法区中,在JDK7之后就放到了堆中。intern方法,它是一个Native方法,如果字符串常量池已经包含一个等于此字符串的对象,则返回池中的对象;否则,将此对象添加到常量池,返回此对象的引用。所以,以下问题就得到了解决。

String str1="abc"; 
String str2=new String("abc"); 
System.out.println(str1==str2.intern());//true

c)String还可以存储null值,他表示目前没有任何对象与该变量关联。要检查一个字符串不为null也不为空串的条件是

if(str!=null&&str.length()!=0)

d)常用方法:

int length();语法:字符串变量名.length();返回值为 int 类型。得到一个字符串的字符个数(中、英、空格、转义字符皆为字符,计入长度)

char charAt(值);语法 :字符串名.charAt(值);返回值为char类型,从字符串中取出指定位置的字符 

char  toCharArray();语法 :字符串名.toCharArray();返回值为 char 数组类型。将字符串变成一个字符数组 

int indexOf("字符")  语法 :字符串名.indexOf("字符");字符串名.indexOf("字符",值);查找一个指定的字符串是否存在,返回的是字符串的位置,如果不存在,则返回-1 。 

in lastIndexOf("字符")得到指定内容最后一次出现的下标

toUpperCase();  toLowerCase();字符串大小写的转换

String[] split("字符")根据给定的正则表达式的匹配来拆分此字符串。形成一个新的String数组。

boolean equals(Object anObject)语法 :字符串变量名.wquals(字符串变量名); 返回值为布尔类型。所以这里用 if 演示。比较两个字符串是否相等,返回布尔值

trim();去掉字符串左右空格

replace(char oldChar,char newChar);新字符替换旧字符,也可以达到去空格的效果一种。

String replaceAll(String,String) 将某个内容全部替换成指定内容,

String repalceFirst(String,String) 将第一次出现的某个内容替换成指定的内容

boolean equalsIgnoreCase(String) 忽略大小写的比较两个字符串的值是否一模一样,返回一个布尔值

boolean contains(String) 判断一个字符串里面是否包含指定的内容,返回一个布尔值 boolean startsWith(String)测试此字符串是否以指定的前缀开始。返回一个布尔值

boolean endsWith(String)测试此字符串是否以指定的后缀结束。返回一个布尔值

String有优点同时存在很多局限性:如果要用较短的字符串构建字符串,如果是使用String的话,每次连接都会产生新的String对象,既耗时又浪费空间,而此时StringBuilder产生了,可以很好的这个解决问题。

StringBuilder和StringBuffer:

一个可变的字符序列,内部也是一个字符数组。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。

1)在StringBuilder和StringBufer上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而insert方法则在指定的点添加字符。

2)两者的对比:StringBuileder的效率高,但是多线程不安全,不保证同步,没有synchronized,他适合适用于单线程下在字符缓冲区进行大量操作的情况;StringBuffer的效率低,是多线程安全,有synchronized,是同步的,他适合适用于多线程下在字符缓冲区进行大量操作的情况。

3)String、StringBuilder、StringBuffer三者的执行效率:StringBuilder > StringBuffer > String

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值