当前位置: 首页 > news >正文

Java StringBuffer 和 StringBuilder 类详解

在 Java 中,StringBufferStringBuilder是用于处理可变字符串的两个重要类。它们弥补了String类不可变的局限性,提供了高效的字符串操作能力。本文将深入解析这两个类的核心特性、性能差异及应用场景。

一、核心特性对比

1. 继承结构与接口实现

  • StringBuffer
    public final class StringBufferextends AbstractStringBuilderimplements java.io.Serializable, CharSequence { ... }
    
     
  • StringBuilder
    public final class StringBuilderextends AbstractStringBuilderimplements java.io.Serializable, CharSequence { ... }
    
     

    • 相同点:均继承AbstractStringBuilder,实现SerializableCharSequence接口。
    • 不同点StringBuffer所有公开方法均被synchronized修饰,线程安全;StringBuilder非线程安全。

2. 内部实现

  • 可变字符数组:两者均使用char[]存储字符序列,但StringBuilder的方法无同步开销。
  • 自动扩容:当容量不足时,内部数组会自动扩容(默认扩容为原容量的2倍 + 2)。

二、常用方法

1. 基础操作

// 初始化
StringBuilder sb = new StringBuilder("Hello");// 添加内容
sb.append(", World!");  // 结果:"Hello, World!"
sb.insert(5, " Java");  // 结果:"Hello Java, World!"// 修改内容
sb.replace(6, 10, "Kotlin");  // 结果:"Hello Kotlin, World!"
sb.delete(5, 12);  // 结果:"Hello, World!"// 反转字符串
sb.reverse();  // 结果:"!dlroW ,olleH"
 

2. 容量管理

StringBuilder sb = new StringBuilder(10);  // 初始容量10
sb.ensureCapacity(20);  // 确保容量至少为20
int capacity = sb.capacity();  // 获取当前容量
 

3. 转换为 String

String result = sb.toString();  // 生成不可变String对象
 

三、性能对比

1. 测试代码示例

// 测试环境:JDK 17,循环100万次
public class StringBuilderVsBuffer {public static void main(String[] args) {int iterations = 1_000_000;// StringBuilder测试long start = System.currentTimeMillis();StringBuilder sb = new StringBuilder();for (int i = 0; i < iterations; i++) {sb.append("a");}System.out.println("StringBuilder耗时:" + (System.currentTimeMillis() - start) + "ms");// StringBuffer测试start = System.currentTimeMillis();StringBuffer sbuffer = new StringBuffer();for (int i = 0; i < iterations; i++) {sbuffer.append("a");}System.out.println("StringBuffer耗时:" + (System.currentTimeMillis() - start) + "ms");}
}
 

2. 典型测试结果

操作次数StringBuilder 耗时StringBuffer 耗时
10 万次 ~5ms ~15ms
100 万次 ~10ms ~50ms
1000 万次 ~50ms ~200ms

结论:在单线程环境下,StringBuilder的性能通常比StringBuffer快 3-5 倍,主要因为无需同步开销。

四、线程安全分析

1. StringBuffer 的线程安全机制

// StringBuffer的append方法(带同步锁)
@Override
public synchronized StringBuffer append(String str) {toStringCache = null;super.append(str);return this;
}
 

2. 多线程场景测试

// 模拟多线程环境下的字符串拼接
public class ThreadSafetyTest {private static StringBuilder sb = new StringBuilder();private static StringBuffer sbuffer = new StringBuffer();public static void main(String[] args) throws InterruptedException {int threadCount = 10;Thread[] threads = new Thread[threadCount];// StringBuilder测试(线程不安全)for (int i = 0; i < threadCount; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < 1000; j++) {sb.append("a");}});threads[i].start();}for (Thread t : threads) t.join();System.out.println("StringBuilder长度:" + sb.length());  // 可能小于10000// StringBuffer测试(线程安全)for (int i = 0; i < threadCount; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < 1000; j++) {sbuffer.append("a");}});threads[i].start();}for (Thread t : threads) t.join();System.out.println("StringBuffer长度:" + sbuffer.length());  // 必定等于10000}
}
 

五、应用场景选择

1. 推荐使用 StringBuilder 的场景

  • 单线程环境下的字符串拼接(如局部变量使用)
  • 性能敏感的操作(如循环中大量拼接)
  • 无需考虑线程安全的场景

2. 推荐使用 StringBuffer 的场景

  • 多线程环境下的共享变量操作
  • 要求线程安全的字符串操作(如 Servlet 中的全局变量)
  • 与遗留代码兼容(早期版本仅提供 StringBuffer)

3. 避免使用 + 拼接字符串的场景

// 低效方式(循环中使用+)
String result = "";
for (int i = 0; i < 1000; i++) {result += i;  // 每次循环创建新String对象
}// 高效方式(使用StringBuilder)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {sb.append(i);  // 仅创建一个StringBuilder对象
}
 

六、最佳实践与注意事项

1. 初始化容量优化

// 预估容量,减少扩容次数
StringBuilder sb = new StringBuilder(1000);  // 初始容量1000
 

2. 链式调用

// 利用返回值实现链式调用
sb.append("a").append("b").insert(0, "prefix");
 

3. 转换为 String 的时机

// 避免频繁转换为String
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {sb.append(i);
}
String result = sb.toString();  // 仅在需要时转换
 

4. Java 8 + 的 StringJoiner

// 更适合处理分隔符连接(如CSV生成)
StringJoiner joiner = new StringJoiner(", ", "[", "]");
joiner.add("Apple").add("Banana").add("Cherry");
String result = joiner.toString();  // 结果:"[Apple, Banana, Cherry]"
 

七、常见面试问题

  1. String、StringBuffer 和 StringBuilder 的区别?
    • String:不可变,每次操作生成新对象
    • StringBuffer:可变,线程安全,性能较低
    • StringBuilder:可变,非线程安全,性能高
  2. StringBuffer 如何保证线程安全?
    • 所有公开方法使用synchronized修饰,确保同一时间只有一个线程访问。
  3. 在循环中使用 + 拼接字符串有什么问题?
    • 会生成大量临时 String 对象,导致频繁 GC,性能低下。
http://www.jsqmd.com/news/420047/

相关文章:

  • 一文彻底讲清,Agent、Agent Framework、Agent Harness 的本质区别
  • 学长亲荐 9个降AI率工具测评:MBA论文降AI率全攻略
  • 2026年全球合同管理系统公司图谱:重塑企业合规底座的数智化利器 - 星野科技
  • 【节点】[LinearBlendSkinning节点]原理解析与实际应用
  • SmartDapper.Repository
  • 数智化风控新标杆:2026年度合同管理系统公司核心竞争力调研报告 - 星野科技
  • 2026年通信工程师中级《综合能力》希赛培训笔记
  • 2025年口碑之选:国内热门重型货架品牌与产品推荐,库房货架/仓储重型货架/库房重力式货架,重型货架厂家哪个好 - 品牌推荐师
  • 2026年靠谱的静电纺丝设备/静电纺丝设备生产线可靠供应商参考哪家靠谱(可靠) - 行业平台推荐
  • 探讨衡水博利口碑如何,技术水平和在广西的合作案例多吗 - 工业推荐榜
  • Navicat Premium 17.1 绿色版使用教程
  • 2026年效果型短视频代运营企业实力推荐公司 - 行业平台推荐
  • 2026年NPDP新产品开发专业人士认证从哪里开始备考?
  • 2026年靠谱的乙炔气瓶检测设备/石油气瓶检测设备哪家质量好生产商实力参考 - 行业平台推荐
  • 如何高效回收永辉超市购物卡,简单又安全! - 团团收购物卡回收
  • 2026年评价高的流水线激光喷码机/激光喷码机销售厂家推荐哪家好(真实参考) - 行业平台推荐
  • 合同管理系统公司选型白皮书:2026数智化风控品牌渗透率分析 - 星野科技
  • 穿透财法边界:2026年度全球合同管理系统公司价值透视白皮书 - 星野科技
  • 永辉超市卡回收方法揭秘 - 团团收购物卡回收
  • 2026年口碑好的胶木球畅销生产厂家采购指南怎么选 - 行业平台推荐
  • 重庆OC商务ktv联系电话大全|官方正规渠道,高端宴请不踩坑 - damaigeo
  • 2026年2月家中常备的孕妇便秘产品推荐,守护孕期肠道健康 - 品牌鉴赏师
  • 鼎诚人寿北京分公司:故居仰贤,清风育企——宋庆龄故居清廉文化学习纪实 - 资讯焦点
  • 2026年口碑好的电加热沥青罐沥青设备/独立加温沥青设备推荐几家可靠供应商参考 - 行业平台推荐
  • 2026中国合同管理系统公司排名:内资领跑与全球巨头深度测评 - 星野科技
  • 2026年B2B社媒营销服务公司评选报告 - 资讯焦点
  • 2026年2月重型数控车床厂家推荐,工业级加工品质认证 - 品牌鉴赏师
  • AI降AI实测:从65%到14%,这些工具让我告别熬夜改论文 - 老米_专讲AIGC率
  • NMN哪个品牌效果好?2026优质NMN抗衰产品成分测评,NMN哪个产品最好?综合临床数据+用户口碑 - 资讯焦点
  • AtCoder Weekday Contest 0005 Beta题解(AWC 0005 Beta A-E)