97. Java 数字和字符串 - StringBuilder 类详解

148 阅读4分钟

97. Java 数字和字符串 - StringBuilder 类详解

1. 概述

Java 中,StringStringBuilder 都用于表示字符序列,但它们的最大区别在于可变性

  • String 对象是 不可变 的(immutable)。每次对 String 进行修改时,都会创建一个新的字符串对象。
  • StringBuilder可变 的(mutable),可以在原对象上进行修改,提高效率。

何时使用 StringBuilder

  • 当字符串需要频繁修改(如拼接、删除、插入等),StringBuilder 性能更优。
  • Java SE 9 之前,大量字符串拼接推荐使用 StringBuilder,因为它比 + 拼接更高效。但在 Java 9 及以后,字符串拼接得到了优化,性能接近 StringBuilder

2. 长度与容量

StringBuilder 提供了两个重要概念:

  • length():表示字符串的实际长度(字符数)。
  • capacity():表示分配的字符存储空间(默认 16),可根据需要自动扩展。

示例代码:

StringBuilder sb = new StringBuilder();
System.out.println("初始长度: " + sb.length());      // 0
System.out.println("初始容量: " + sb.capacity());    // 16

sb.append("Hello, World!");
System.out.println("新长度: " + sb.length());        // 13
System.out.println("新容量: " + sb.capacity());    // 16(仍然足够,不会扩展)

容量扩展规则 🔥StringBuilder 超过当前容量时,它的容量会自动扩展为:

新容量 = (旧容量 * 2) + 2

手动扩展容量 可以使用 ensureCapacity(int minCapacity) 方法提前扩展容量,避免频繁扩容影响性能。

sb.ensureCapacity(50);
System.out.println("扩展后的容量: " + sb.capacity());

3. 构造方法

StringBuilder 提供了以下几种构造方式:

// 1. 默认构造:容量为 16
StringBuilder sb1 = new StringBuilder();

// 2. 指定初始容量
StringBuilder sb2 = new StringBuilder(50);

// 3. 以现有字符串初始化
StringBuilder sb3 = new StringBuilder("Hello");

// 4. 以 CharSequence(如 StringBuffer)初始化
CharSequence cs = "Java";
StringBuilder sb4 = new StringBuilder(cs);

4. StringBuilder 主要方法

4.1 追加字符串 append()

append() 方法可以将任意数据类型(字符串、数值、对象等)追加到末尾。

StringBuilder sb = new StringBuilder("Hello");
sb.append(", ").append("World").append("!");
System.out.println(sb.toString());  // Hello, World!

4.2 插入字符串 insert()

在指定位置插入字符串或数据。

StringBuilder sb = new StringBuilder("HelloWorld");
sb.insert(5, ", ");
System.out.println(sb.toString());  // Hello, World

4.3 删除字符 delete()deleteCharAt()

delete(int start, int end): 删除 startend-1 位置的字符。

StringBuilder sb = new StringBuilder("Hello, World!");
sb.delete(5, 7);
System.out.println(sb.toString());  // HelloWorld!

deleteCharAt(int index): 删除指定索引位置的字符。

sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());  // HelloWorld

4.4 替换字符 replace()

replace(int start, int end, String s): 替换 startend-1 的字符。

StringBuilder sb = new StringBuilder("Hello, World!");
sb.replace(7, 12, "Java");
System.out.println(sb.toString());  // Hello, Java!

4.5 修改单个字符 setCharAt()

StringBuilder sb = new StringBuilder("Java");
sb.setCharAt(0, 'Y');
System.out.println(sb.toString());  // Yava

4.6 反转字符串 reverse()

StringBuilder sb = new StringBuilder("Java");
sb.reverse();
System.out.println(sb.toString());  // avaJ

4.7 转换为 String

StringBuilder 可以随时转换回 String

StringBuilder sb = new StringBuilder("Hello, Java!");
String str = sb.toString();
System.out.println(str);

5. StringBuilder 的实际应用

字符串反转:使用 StringBuilder 替代 char[]

传统方式(使用 char[]
public class StringDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
        char[] charArray = palindrome.toCharArray();
        
        for (int i = 0, j = charArray.length - 1; i < j; i++, j--) {
            char temp = charArray[i];
            charArray[i] = charArray[j];
            charArray[j] = temp;
        }
        
        System.out.println(new String(charArray));  // doT saw I was toD
    }
}
优化方式(使用 StringBuilder
public class StringBuilderDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
        StringBuilder sb = new StringBuilder(palindrome);
        sb.reverse();
        System.out.println(sb);  // doT saw I was toD
    }
}

StringBuilderreverse() 方法让代码更简洁,避免了字符数组的手动操作。

📌 注意: StringBufferStringBuilder 基本相同,但 StringBuffer线程安全 的,方法经过同步处理。如果不涉及多线程环境,推荐使用 StringBuilder 以获得更高性能。

6. String vs StringBuilder

操作String(不可变)StringBuilder(可变)
追加操作创建新对象直接修改,提高性能
插入操作创建新对象直接修改,提高性能
删除操作创建新对象直接修改,提高性能
线程安全性线程安全非线程安全
适用场景需要不可变数据需要频繁修改字符串

总结:如果需要多线程安全,请使用 StringBuffer(线程安全版的 StringBuilder)。否则 StringBuilder 性能更高。


7. StringBuilder 使用建议 ✅

  1. 避免不必要的 toString() 转换,因为 StringBuilder 直接操作可变字符序列。
  2. 避免频繁扩容,如果能预估字符串长度,建议使用 ensureCapacity(int capacity) 提前分配。
  3. 非线程安全,多线程环境下使用 StringBuffer
  4. 适用于循环拼接字符串,如日志输出、动态 SQL 拼接等。

示例:避免创建过多 String 对象 🔥

// 不推荐 ❌
String str = "";
for (int i = 0; i < 1000; i++) {
    str += i;  // 每次循环创建新对象
}

// 推荐 ✅
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

📌 总结:

  • StringBuilder 适用于需要频繁修改字符串的场景。
  • StringBuilder 提供了 appendinsertdeletereplacereverse 等高效操作。
  • 适量使用 ensureCapacity() 以优化性能。
  • StringBuilder 非线程安全,多线程场景使用 StringBuffer

🚀 掌握 StringBuilder,让你的 Java 代码更高效!