源本科技 | 码上会

Java 中的 StringBuilder 类

2025/12/26
23
0

学习目标

  • 掌握 StringBuilder 的可变性与高性能特性

  • 熟练使用核心方法(appendinsertreplacereverse 等)进行字符串操作

  • 能在 StringStringBufferStringBuilder 之间做出合理选择

  • 理解容量管理机制对性能的影响


什么是 StringBuilder

StringBuilderjava.lang 包中提供的一个可变字符序列类。它允许在不创建新对象的前提下直接修改内容,从而显著提升频繁字符串操作的性能。

关键特点

  • 可变:内容可原地修改

  • 非线程安全:无同步开销

  • 高性能:单线程环境下优于 StringBuffer

public class CoderHub {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Java");
        System.out.println("初始: " + sb);
        
        sb.append(" is awesome!");
        System.out.println("追加后: " + sb);
    }
}

输出

初始: Java
追加后: Java is awesome!

💡 append() 直接修改原对象,避免了 String 拼接时产生的大量中间对象。


StringBuilder 构造方法

构造器

说明

StringBuilder()

创建空对象,默认容量 16

StringBuilder(int capacity)

指定初始容量

StringBuilder(String str)

用字符串初始化,容量 = str.length() + 16

StringBuilder(CharSequence cs)

从任意 CharSequence(如 StringStringBuffer)初始化

// 1. 默认构造
StringBuilder sb1 = new StringBuilder();
sb1.append("Hello");

// 2. 指定容量(优化性能)
StringBuilder sb2 = new StringBuilder(50);
sb2.append("This has initial capacity 50");

// 3. 从字符串初始化
StringBuilder sb3 = new StringBuilder("Hello");
sb3.append("World");

// 4. 从 CharSequence 初始化
CharSequence cs = "Java";
StringBuilder sb4 = new StringBuilder(cs);
sb4.append("Programming");

System.out.println(sb1); // Hello
System.out.println(sb2); // This has initial capacity 50
System.out.println(sb3); // HelloWorld
System.out.println(sb4); // JavaProgramming

重要方法速查

方法

功能

示例

append(str)

末尾追加

sb.append("World")

insert(offset, str)

指定位置插入

sb.insert(0, "Hi ")

replace(start, end, str)

替换区间内容

sb.replace(0, 5, "Hello")

delete(start, end)

删除区间

sb.delete(0, 1)

deleteCharAt(index)

删除单个字符

sb.deleteCharAt(0)

reverse()

反转整个序列

sb.reverse()

setCharAt(index, ch)

修改指定位置字符

sb.setCharAt(0, 'A')

charAt(index)

获取指定位置字符

char c = sb.charAt(0)

substring(start, end)

截取子串(返回 String

String s = sb.substring(0, 5)

indexOf(str) / lastIndexOf(str)

查找子串位置

int i = sb.indexOf("Java")

length()

当前字符数

int len = sb.length()

capacity()

当前缓冲区容量

int cap = sb.capacity()

ensureCapacity(min)

确保最小容量

sb.ensureCapacity(100)

toString()

转为不可变 String

String s = sb.toString()


容量管理机制

  • 默认容量:16

  • 扩容策略:当空间不足时,新容量 = (旧容量 × 2) + 2

  • 手动控制

    • ensureCapacity(int min):确保容量 ≥ min

    • trimToSize():将容量缩减至当前长度(节省内存)

性能建议:若预知操作后的最大长度,初始化时指定足够容量可避免多次内存拷贝。


StringBuilder vs StringBuffer vs String

特性

String

StringBuilder

StringBuffer

可变性

❌ 不可变

✅ 可变

✅ 可变

线程安全

✅(因不可变)

✅(方法同步)

性能

慢(频繁创建对象)

最快

中等(同步开销)

适用场景

内容固定

单线程高频操作

多线程高频操作

选择原则

// 单线程 → StringBuilder
StringBuilder sb = new StringBuilder();

// 多线程 → StringBuffer
StringBuffer sb = new StringBuffer();

// 内容不变 → String
String s = "Constant";

重点总结

  • StringBuilder单线程下字符串操作的首选

  • 所有修改方法(appendinsert 等)返回自身引用,支持链式调用

  • 默认容量 16,超限时自动扩容(公式:old*2+2

  • 非线程安全,多线程环境需额外同步或改用 StringBuffer

  • 最终通过 toString() 转为标准 String 对象供外部使用

💡 最佳实践:在循环中拼接字符串时,务必使用 StringBuilder,避免 String 的指数级性能下降。


思考题

  1. 为什么 StringBuilderappend() 方法返回 this?这种设计带来了什么编程便利?

  2. 编写一个方法,使用 StringBuilder 实现“去除字符串中所有空格”的功能,并分析其时间复杂度。

  3. 如果在多线程环境中错误地使用了 StringBuilder,可能出现什么问题?如何通过代码复现并验证?