Java字符串之StringBuffer和StringBuilder模拟栈

本文介绍了Java中的StringBuffer和StringBuilder类在字符串拼接中的优势,并详细探讨了如何使用StringBuffer模拟栈来解决LeetCode的三个问题:1047. 删除字符串中的所有相邻重复项,1209. 删除字符串中的所有相邻重复项 II,以及1249. 移除无效的括号。通过实例展示了StringBuilder在模拟栈操作中的应用。

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

1. StringBuffer与StringBuilder

  1. StringBuffer和StringBuilder与String之间的主要区别
  • String是不可变对象, 当用String类拼接字符串时, 每次都会生成一个StringBuilder对象, 然后调用两次append()方法把字符串拼接好, 最后通过StringBuilder的toString()方法new出一个新的字符串对象。也就是说每次拼接都会new出两个对象, 并进行两次方法调用, 如果拼接的次数过多, 创建对象所带来的时延会降低系统效率, 同时会造成巨大的内存浪费. 而且当内存不够用时, 虚拟机会进行垃圾回收, 这也是一项相当耗时的操作, 会大大降低系统性能。
  • 当对字符串进行修改的时候,特别是字符串对象经常改变的情况下,需要使用 StringBuffer 和 StringBuilder 类,它们拼接字符串就简单多了, 直接把要拼接的字符串放到栈顶进行append就完事了, 除了开始时创建了StringBuilder和StringBuffer 对象, 运行时期没有创建过其他任何对象, 每次循环只调用一次append方法. 所以从效率上看, 拼接大量字符串时, StringBuilder要比String类给力得多。
  1. StringBuffer和StringBuilder对比
是否可变 效率 线程是否安全 应用场景
StringBuffer 可变 线程安全 多线程操作
StringBuilder 可变 线程不安全 单线程操作

注意:
StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。StringBuffer类中的方法都添加了synchronized关键字,这个关键字是为线程同步机制设定的,用来保证线程安全。

2. StringBuffer和StringBuilder类的主要方法

二者方法类似,这里只列举StringBuffer类的方法。

2.1 append方法

在这里插入图片描述
append方法可以将各种类型的变量转化为字符串然后加入StringBuffer中

2.2 insert方法

在这里插入图片描述
insert方法可以将各种类型的变量转化为字符串然后插入StringBuffer中

2.3 其他方法

方法 方法返回类型 作用
charAt(int index) char 返回 char在指定索引在这个序列值
delete(int start, int end) StringBuffer 删除子串索引为start到end - 1
deleteCharAt(int index) StringBuffer 删除索引为index的字符
indexOf(String str) int 返回字符串第一次出现的索引
indexOf(String str, int fromIndex) char 返回字符串第一次出现的索引,从指定的索引开始
lastIndexOf(String str) int 返回字符串最后一次出现的索引
lastIndexOf(String str, int fromIndex) char 返回字符串最后一次出现的索引,从指定的索引开始
replace(int start, int end, String str) StringBuffer 用指定的String中的字符替换此序列的子字符串中的 String
reverse() StringBuffer 反转字符串
setCharAt(int index, char ch) void 指定索引处的字符设置为 ch
toString() String 返回表示此顺序中的数据的字符串

3. StringBuffer模拟栈

3.1 栈的主要操作:

  1. 用一个top指针始终指向栈顶,当栈为空时,top = -1
  2. 元素入栈时,1)添加元素2)top++
  3. 元素出栈时,先判断top >= 0保证栈不为空,1)删除元素2)top--
  4. 实际上StringBuffer,StringBuilder,List等变长的类均能模拟栈
  5. 好处:不用实际定义栈,节省内存空间

3.2 应用

3.2.1 leetcode-1047. 删除字符串中的所有相邻重复项

1047. 删除字符串中的所有相邻重复项
在这里插入图片描述
对于"abba"结构,删除"bb"会导致"aa"出现需要继续删除,即相邻两项进行匹配,出现相同的就进行删除,而**匹配问题是栈的强项**。这里使用StringBuilder模拟栈。

class Solution {
   
    public String removeDuplicates(String s) {
   
Java中,String是一个不可变的对象,而StringBuilderStringBuffer则是可变的。为了测试它们在大量字符串拼接操作下的性能差异,你可以编写如下的简单程序: ```java public class StringPerformanceTest { public static void main(String[] args) { int iterations = 100000; // 迭代次数,可以调整以观察更细致的性能差异 long startTime = System.currentTimeMillis(); // 开始时间标记 // 使用String for (int i = 0; i < iterations; i++) { String str = ""; for (int j = 0; j < 100; j++) { str += "test"; } } long endTimeString = System.currentTimeMillis() - startTime; // 使用StringBuilder StringBuilder stringBuilder = new StringBuilder(); startTime = System.currentTimeMillis(); for (int i = 0; i < iterations; i++) { for (int j = 0; j < 100; j++) { stringBuilder.append("test"); } } long endTimeStringBuilder = System.currentTimeMillis() - startTime; // 使用StringBuffer,由于线程安全,这里需要同步上下文 StringBuffer stringBuffer = new StringBuffer(); synchronized (stringBuffer) { startTime = System.currentTimeMillis(); for (int i = 0; i < iterations; i++) { for (int j = 0; j < 100; j++) { stringBuffer.append("test"); } } } long endTimeStringBuffer = System.currentTimeMillis() - startTime; System.out.println("With String:"); System.out.println("Time taken: " + endTimeString + "ms"); System.out.println("With StringBuilder:"); System.out.println("Time taken: " + endTimeStringBuilder + "ms"); System.out.println("With StringBuffer (synchronized):"); System.out.println("Time taken: " + endTimeStringBuffer + "ms"); // 相关问题:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值