网站首页 > java教程 正文
#Java基础 #字符串处理 #性能优化 #面试必备
一、核心区别:线程安全与性能取舍
特性 | StringBuffer | StringBuilder |
线程安全 | 所有方法同步(synchronized) | 非线程安全 |
性能 | 较低(同步开销) | 较高(无同步开销) |
JDK版本 | 1.0+ | 1.5+ |
适用场景 | 多线程环境 | 单线程环境 |
二、底层原理揭秘
1. 继承关系
public final class StringBuffer
extends AbstractStringBuilder
implements Serializable, Comparable<StringBuffer>, CharSequence
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
两者共享同一父类AbstractStringBuilder,底层均使用可扩容的char数组实现。
2. 扩容机制
- 初始容量:16字符
- 扩容规则:新容量 = (原容量 * 2) + 2
- 触发条件:当前长度+新内容长度 > 当前容量
三、常用方法实战(两者API完全一致)
1. 初始化与容量控制
// 指定初始容量(避免频繁扩容)
StringBuilder sb = new StringBuilder(100);
// 获取当前容量
int capacity = sb.capacity();
// 主动扩容
sb.ensureCapacity(200);
2. 增删改查操作
// 追加内容(支持链式调用)
sb.append("Hello").append(" ").append(2024);
// 指定位置插入
sb.insert(5, " World"); // Hello World 2024
// 删除子串
sb.delete(0, 6); // World 2024
// 替换内容
sb.replace(6, 10, "Java"); // World Java
// 反转字符串
sb.reverse(); // avaJ dlroW
// 清空缓冲区
sb.setLength(0);
3. 字符串转换
// 转String对象
String result = sb.toString();
// 截取子串(不影响原对象)
String sub = sb.substring(0, 5);
// 获取指定位置字符
char ch = sb.charAt(2);
四、性能对比测试
public class PerformanceTest {
public static void main(String[] args) {
int loopCount = 100000;
// StringBuilder测试
long start1 = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < loopCount; i++) {
sb.append(i);
}
long time1 = System.nanoTime() - start1;
// StringBuffer测试
long start2 = System.nanoTime();
StringBuffer sf = new StringBuffer();
for (int i = 0; i < loopCount; i++) {
sf.append(i);
}
long time2 = System.nanoTime() - start2;
System.out.printf("StringBuilder耗时:%.2fms%n", time1/1e6);
System.out.printf("StringBuffer耗时:%.2fms%n", time2/1e6);
}
}
/* 典型输出:
StringBuilder耗时:3.15ms
StringBuffer耗时:8.74ms */
五、开发最佳实践
- 单线程环境必选StringBuilder 循环体内字符串拼接、日志构建等场景优先使用。
- 预估初始容量 避免频繁扩容,提升性能:
// 错误示范:默认容量16
StringBuilder sb = new StringBuilder();
// 正确做法:预估最终长度
StringBuilder sb = new StringBuilder(1024);
- 避免与String混用
错误示例:
String str = "";
for (int i=0; i<10000; i++) {
str += i; // 每次循环创建新StringBuilder对象
}
正确优化:
StringBuilder sb = new StringBuilder();
for (int i=0; i<10000; i++) {
sb.append(i);
}
String str = sb.toString();
六、高频面试题解析
Q1:为什么StringBuilder比StringBuffer快? 省去synchronized同步锁的开销,减少线程竞争带来的性能损耗。
Q2:两者是否都实现Serializable接口? 是,但实际序列化时需要自定义writeObject/readObject方法处理char数组。
Q3:如何实现线程安全的StringBuilder? 方案一:使用
Collections.synchronizedList包装 方案二:自定义同步方法(不推荐,应直接使用StringBuffer)
七、总结选择策略
场景 | 推荐类 | 理由 |
单线程字符串操作 | StringBuilder | 性能最优 |
多线程共享字符串操作 | StringBuffer | 保证线程安全 |
方法局部变量 | StringBuilder | JVM栈封闭,天然线程安全 |
静态变量/类成员变量 | StringBuffer | 可能被多线程访问 |
猜你喜欢
- 2025-05-02 Spring框架双核解析:IOC与AOP的本质与实战
- 2025-05-02 应聘者:什么,第一轮面试就用这么简单的算法题?
- 2025-05-02 Go slice切片使用教程,一次通关!
- 2025-05-02 几经反转 谷歌胜诉后甲骨文能否接招?丨C位
- 2025-05-02 java组件HuTool相关工具类的使用二
- 2025-05-02 深入解析 Java 链表:从构建到逆序打印的技术之旅
- 2025-05-02 2023年Java基础面试题目收集整理归纳(持续更新)
- 2025-05-02 我的世界:末地烛的“奇妙”玩法?关于末地棒,你不知道的11件事
- 2025-05-02 程序员去大公司面试,Java岗大厂面试官常问的那些问题,进阶学习
- 2025-05-02 90%人踩过的坑!Java运算符优先级与类型转换的终极避坑指南!
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)