Java字符串之StringBuffer和StringBuilder模拟栈

1. StringBuffer与StringBuilder

  1. StringBuffer和StringBuilder与String之间的主要区别
  • String是不可变对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串不要用 String 。
  • 当对字符串进行修改的时候,特别是字符串对象经常改变的情况下,需要使用 StringBuffer 和 StringBuilder 类。
  1. StringBuffer和StringBuilder对比
是否可变 效率 线程是否安全 应用场景
StringBuffer 可变 线程安全 多线程操作
StringBuilder 可变 线程不安全 单线程操作

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

2. StringBuffer和StringBuilder类的主要方法

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

2.1 append方法

Java字符串之StringBuffer和StringBuilder模拟栈
append方法可以将各种类型的变量转化为字符串然后加入StringBuffer中

2.2 insert方法

Java字符串之StringBuffer和StringBuilder模拟栈
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 返回字符串第一次出现的索引,从指定的索引开始
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. 删除字符串中的所有相邻重复项
Java字符串之StringBuffer和StringBuilder模拟栈
对于"abba"结构,删除"bb"会导致"aa"出现需要继续删除,即相邻两项进行匹配,出现相同的就进行删除,而**匹配问题是栈的强项**。这里使用StringBuilder模拟栈。

class Solution {
    public String removeDuplicates(String s) {
        StringBuilder res = new StringBuilder();
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (top >= 0 && ch == res.charAt(top)) {
                res.deleteCharAt(top);
                top--;
            } else {
                res.append(ch);
                top++;
            }
        }
        return res.toString();
    }
}

3.2.2 leetcode-1209. 删除字符串中的所有相邻重复项 II

1209. 删除字符串中的所有相邻重复项 II
Java字符串之StringBuffer和StringBuilder模拟栈
这里可以使用双栈:一个栈用StringBuilder模拟,来保存字符;一个栈用于计数。

class Solution {
    public String removeDuplicates(String s, int k) {
        StringBuilder sb = new StringBuilder();
        Stack<Integer> stack = new Stack<>();
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (top >= 0 && (ch == sb.charAt(top)) && stack.peek() == k -1) {
                int count = k - 1;
                stack.pop();
                while (count > 0) {
                    sb.deleteCharAt(top);
                    top--;
                    count--;
                }
            } else {
                sb.append(ch);
                if (top >= 0 && (ch == sb.charAt(top)) && stack.peek() != k -1)
                    stack.push(stack.pop() + 1);   
                else 
                    stack.push(1);
                top++;
            }
        }
        return sb.toString();  
    }
}
上一篇:为什么说 StringBuilder 是线程不安全的且会发生数组越界问题而 StringBuffer 是线程安全的?


下一篇:剑指 Offer 38. 字符串的排列