亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> java

Java StringBuilder 与 StringBuffer:高性能字符串操作

Java StringBuilder 与 StringBuffer:高性能字符串操作

深入对比 StringBuilder 与 StringBuffer,掌握可变字符串的高效构建、线程安全差异、性能基准与最佳实践。

为什么需要可变字符串?

Java 中 String 是不可变的。每次拼接、修改都会创建新对象,频繁操作导致大量临时对象、GC 压力和性能下降。

String s = "Hello";
s += " World"; // 实际创建新 String 对象,原 "Hello" 成垃圾

为解决此问题,Java 提供 StringBuilder (非线程安全、高性能) 和 StringBuffer (线程安全、同步开销)。


核心区别对比

特性StringBuilderStringBuffer
线程安全否 (非同步)是 (方法同步)
性能高 (无锁开销)较低 (同步开销)
引入版本JDK 5JDK 1.0
适用场景单线程、高频拼接多线程共享字符串缓冲区
API 兼容性与 StringBuffer 几乎相同遗留 API,部分方法已弃用

StringBuilder 核心方法

构造器

StringBuilder()
StringBuilder(int capacity)
StringBuilder(String str)
StringBuilder(CharSequence seq)

常用实例方法

方法描述
append(...)追加各类数据 (重载支持所有基本类型、对象、CharSequence)
insert(int offset, ...)在指定位置插入数据
delete(int start, int end)删除指定范围字符
deleteCharAt(int index)删除指定位置字符
replace(int start, int end, String str)替换指定范围为新字符串
reverse()反转字符序列
charAt(int index)获取指定位置字符
setCharAt(int index, char ch)设置指定位置字符
substring(int start)返回子序列 (不创建新 String 直到 toString())
substring(int start, int end)返回指定范围子序列
length()当前字符数
capacity()当前容量 (不扩容可容纳字符数)
ensureCapacity(int minimumCapacity)确保最小容量
trimToSize()缩减容量至当前长度
toString()转为不可变 String

StringBuffer 核心方法

StringBuffer 方法与 StringBuilder 签名几乎相同,区别在于所有公共方法均声明 synchronized。

额外遗留方法:


性能基准测试

public class Benchmark {
    public static void main(String[] args) {
        int iterations = 100_000;
        // String 拼接
        long t1 = System.nanoTime();
        String s = "";
        for (int i = 0; i < iterations; i++) s += "a";
        long t2 = System.nanoTime();
        System.out.println("String += : " + (t2 - t1) / 1_000_000 + " ms");

        // StringBuilder
        long t3 = System.nanoTime();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < iterations; i++) sb.append("a");
        long t4 = System.nanoTime();
        System.out.println("StringBuilder: " + (t4 - t3) / 1_000_000 + " ms");

        // StringBuffer
        long t5 = System.nanoTime();
        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < iterations; i++) sbf.append("a");
        long t6 = System.nanoTime();
        System.out.println("StringBuffer: " + (t6 - t5) / 1_000_000 + " ms");
    }
}

典型输出 (JDK 17, x86_64):


String += : 4500 ms
StringBuilder: 12 ms
StringBuffer: 18 ms

结论:StringBuilder 比 String += 快 ~375 倍,比 StringBuffer 快 ~1.5 倍。


容量管理与扩容机制


最佳实践

  1. 单线程首选 StringBuilder:无同步开销,性能最优。
  2. 多线程共享缓冲区用 StringBuffer:或用 ThreadLocal 避免共享。
  3. 预分配容量:大概知最终长度时用构造器指定 capacity。
  4. 链式调用:sb.append("a").append("b").append("c") 返回 this,可链式调用。
  5. 避免 toString() 后继续修改:toString() 可能共享底层数组 (JDK 9+ compact strings),后续修改会复制数组。
  6. JSON/日志构建:高吞吐场景配合 StringBuilder 手动拼接优于 String.format()。

常见面试题

Q: StringBuilder 线程安全吗?
A: 否。多线程环境需自行加锁或用 StringBuffer。
Q: StringBuilder 与 StringBuffer 性能差异原因?
A: StringBuffer 所有公共方法 synchronized,锁竞争开销;StringBuilder 无锁。
Q: 何时用 String 而非 StringBuilder?
A: 字符串不常修改、作为 Map 键、需哈希码缓存、跨线程共享不可变对象时。
Q: Java 9+ Compact Strings 对 StringBuilder 有何影响?
A: 内部改用 byte[] + coder 存储,ASCII 字符仅占 1 字节,内存占用减半,追加性能提升。

推荐阅读:Java String 完全指南 | Java 字符串池与 intern() 机制

java

  1. 掌握 C# this 关键字:消歧义、构造函数链、传递实例与索引器
  2. 精通 Java 运算符:类型、语法与实战示例
  3. Java 注释:类型、用法与最佳实践
  4. 精通 Java 增强 for 循环:语法、示例与最佳实践
  5. 精通 Java 构造器:类型、用法与实战示例
  6. 精通 Java 字符串:创建、方法与最佳实践
  7. Java StringBuilder 与 StringBuffer:高性能字符串操作
  8. 深入理解 Java final 关键字:变量、方法与类的不可变性
  9. 精通 Java 接口:概念、实现与最佳实践
  10. 精通 Java 封装:数据隐藏实战指南
  11. 精通 Java 匿名内部类:定义、语法与实战示例
  12. 精通 Java Try-With-Resources:自动资源管理详解