深入理解StringBuilder和StringBuffer

目录

关于String类

StringBuilder和StringBuffer

StringBuffer的使用

StringBuilder和StringBuffer的区别


关于String类

Java中的String类是不可变的 这意味着一旦一个String对象被创建 它包含的字符序列就不能被改变

这里我们可能会想到字符串拼接--->"+"    

实际上 当我们执行字符串拼接时 会创建一个新的String对象来存储拼接后的结果 原有的String对象仍然保持不变 存在于内存中 直到垃圾回收器将其回收

示例:

String s1 = "Hello";  
String s2 = "World";  
String s3 = s1 + ", " + s2; // 字符串拼接

在这里s3并不是通过修改s1或s2来得到的 而是java运行时 在内存中创建了一个新的String对象来存储"Hello,World"这个字符串 并将s3引用指向了这个新对象

由于String的不可变性 为了方便字符串的修改 Java中又提供了StringBuffer和StringBuilder类

StringBuilder和StringBuffer

StringBuffer与StringBuilder都继承自AbstractStringBuilder类

AbstractStringBuilder中也是使用字符数组保存字符串,但其是可变类

StringBuilder和StringBuffer是Java中用于处理可变字符序列的类 允许通过追加、插入和删除等操作来修改字符串内容  而无需创建新的字符串对象 

注意:虽然StringBuilder和StringBuffer是可变的 但它们并不是在”原本的字符串“上进行修改

当我们使用StringBuilder和StringBuffer的append、insert等方法时 只是在其内部维护的字符数组上执行操作(不是原本的字符串上修改)

我们这里只举例StringBuffer   因为StringBuilder和其几乎一致

StringBuffer的使用

1.创建StringBuffer对象

//使用无参构造方法创建一个空的StringBuffer对象
StringBuffer sb = new StringBuffer();

//指定初始容量来创建StringBuffer对象
int initialCapacity = 10; // 初始容量设为10  
StringBuffer sb = new StringBuffer(initialCapacity);

//使用已有的字符序列创建
String str = "Hello, World!";  
StringBuffer sb = new StringBuffer(str);

//使用字符数组创建
char[] charArray = {'H', 'e', 'l', 'l', 'o'};  
StringBuffer sb = new StringBuffer(charArray);

//使用字符数组的子序列创建
char[] charArray = {'J', 'a', 'v', 'a', ' ', 'P', 'r', 'o', 'g', 'r', 'a', 'm'};  
// 从索引2(包含)开始,截取长度为5的子序列  
StringBuffer sb = new StringBuffer(charArray, 2, 5); // 结果为"va Pr"

常用方法

·append(String s):将指定的字符序列追加到此字符序列的末尾

·insert(int offset,String s):将指定字符序列插入此序列中指定的offset位置

·delete(int start,int end):移除此序列的子字符串

·replace(int start,int end,String str):用给定String中的字符替换此序列的子字符串

·reverse():将此字符序列用其反转形式替换

·length():返回此字符序列的长度

·toString():生成此序列的字符串表达形式 --即将StringBuffer变为String

示例:

注意事项:

·在单线程环境下 如果不需要线程安全 推荐使用StringBuilder 因为它比StringBuffer有更好的性能

·StringBuffer的操作(如append、insert等)会返回StringBuffer对象本身 这允许链式调用

·当你需要频繁修改字符串时 使用StringBuilder或StringBuilder而不是String  因为String的每次修改都会创建一个新的字符串对象 这可能导致性能问题

题目案例:https://leetcode.cn/problems/backspace-string-compare/description/

当然本题还有很多其他的方法 在这里我们使用StringBuffer来解决该题

StringBuilder和StringBuffer的区别

1.线程安全性

StringBuffer:是线程安全的   它的所有公开方法都被synchronized修饰,这意呀着在多线程环境下,多个线程可以同时访问和修改同一个StringBuffer实例,而不会导致数据不一致的问题。

StringBuilder:不是线程安全的  它没有对方法进行同步处理,因此在多线程环境下,如果多个线程同时访问和修改同一个StringBuilder实例,可能会导致数据不一致的问题。

2. 性能

StringBuffer:由于所有方法都是同步的,因此在单线程环境下,其性能通常低于StringBuilder。同步机制虽然保证了线程安全,但也引入了额外的性能开销。

StringBuilder:没有同步机制,因此在单线程环境下,其性能通常优于StringBuffer。它更适合用于频繁修改字符串的场景

3. 使用场景

StringBuffer:适用于需要线程安全的场景,如多线程环境下对字符串进行修改。

StringBuilder:适用于单线程环境,当不需要线程安全且追求更好的性能时,选择StringBuilder更为合适

4. 缓冲区与toString方法

StringBuffer:在调用toString方法时,会直接使用缓存区的toStringCache值(如果存在)来构造一个字符串,这有助于优化性能。但需要注意的是,这个toString方法仍然是同步的。

StringBuilder:每次调用toString方法时,都需要复制一次字符数组,再构造一个字符串。这导致在频繁调用toString方法的场景下,StringBuilder的性能可能不如StringBuffer(尽管在大多数情况下,性能差异并不显著,因为toString方法的调用频率通常较低)。

5. 方法和API

StringBuffer和StringBuilder的大部分API是相同的,都提供了追加、插入、删除、替换等字符串操作方法。然而,由于StringBuffer是线程安全的,因此它的某些方法可能会比StringBuilder的方法稍慢一些,因为它们需要处理额外的同步逻辑。

综上所述,StringBuffer和StringBuilder在功能和用法上非常相似,但在线程安全性和性能方面存在显著差异。在选择使用哪一个类时,应根据具体的应用场景和需求来决定

总结

1.字符数组的可变性:StringBuffer 和 StringBuilder 内部使用的是一个可变的字符数组(尽管是私有的,外部不能直接访问)。这意味着它们可以在不需要创建新对象的情况下修改字符串内容。

2.字符串的不可变性:相比之下,String 对象在Java中是不可变的。一旦一个 String 对象被创建,它就不能被修改(即你不能改变它包含的字符序列)。如果你需要修改一个字符串,你必须创建一个新的 String 对象。

3.性能优势:由于 StringBuffer 和 StringBuilder 可以在不创建新对象的情况下修改内容,因此在需要频繁修改字符串的场合(如在循环中构建大型字符串),它们比使用 String 拼接(如使用 + 运算符或 concat 方法)要高效得多。因为每次使用 + 或 concat 进行字符串拼接时,都会创建一个新的 String 对象。

4.线程安全性:StringBuffer 是线程安全的,而 StringBuilder 不是。这意味着在多线程环境中,你应该使用 StringBuffer(但如果你确定只有一个线程会访问 StringBuilder 对象,那么使用 StringBuilder 会获得更好的性能)。

5.构造字符串:虽然 StringBuffer 和 StringBuilder 不需要为了修改内容而构造新的字符串对象,但如果你需要将它们的内容转换为 String 对象(例如,为了打印或将其传递给接受 String 参数的方法),则需要进行一次转换。这个转换操作会创建一个新的 String 对象,但这个过程是高效的,因为它只需要复制内部字符数组的内容(而不需要像使用 + 那样进行多次复制和拼接)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值