String、StringBuffer、StringBuilder 面试题总结
核心区别对比表
特性 |
String |
StringBuffer |
StringBuilder |
可变性 |
❌ 不可变 |
✅ 可变 |
✅ 可变 |
线程安全 |
✅ 安全(不可变) |
✅ 安全(synchronized) |
❌ 不安全 |
性能 |
低(频繁创建新对象) |
中(同步开销) |
高(无同步开销) |
JDK版本 |
1.0 |
1.0 |
1.5 |
继承关系 |
Object → String |
Object → AbstractStringBuilder → StringBuffer |
Object → AbstractStringBuilder → StringBuilder |
使用场景 |
字符串常量、少量操作 |
多线程频繁修改 |
单线程高频修改 |
内存效率 |
低(产生中间对象) |
高 |
高 |
声明与创建方式
String 创建方式
// 1. 字面量方式(推荐)
String str1 = "Hello";
String str2 = "Hello"; // 指向同一个对象
// 2. 构造方法
String str3 = new String("Hello");
String str4 = new String(new char[]{'H','e','l','l','o'});
String str5 = new String("Hello".getBytes());
StringBuffer/StringBuilder 创建方式
// 1. 无参构造(默认容量16)
StringBuffer sb1 = new StringBuffer();
StringBuilder sbd1 = new StringBuilder();
// 2. 指定初始容量
StringBuffer sb2 = new StringBuffer(32);
StringBuilder sbd2 = new StringBuilder(32);

// 3. 通过字符串初始化
StringBuffer sb3 = new StringBuffer("Hello");
StringBuilder sbd3 = new StringBuilder("Hello");
// 4. 通过CharSequence初始化
CharSequence seq = "Hello";
StringBuffer sb4 = new StringBuffer(seq);
StringBuilder sbd4 = new StringBuilder(seq);
常用库函数
String 常用方法
方法 |
说明 |
示例 |
length() |
获取字符串长度 |
"Hello".length() → 5 |
charAt(int index) |
获取指定位置字符 |
"Hello".charAt(1) → 'e' |
substring(int begin) |
截取子串 |
"Hello".substring(2) → "llo" |
substring(int begin, int end) |
截取子串 |
"Hello".substring(1,4) → "ell" |
indexOf(String str) |
查找子串位置 |
"Hello".indexOf("l") → 2 |
lastIndexOf(String str) |
反向查找 |
"Hello".lastIndexOf("l") → 3 |
equals(Object obj) |
内容比较 |
"Hello".equals("hello") → false |
equalsIgnoreCase(String str) |
忽略大小写比较 |
"Hello".equalsIgnoreCase("hello") → true |
toUpperCase() |
转大写 |
"Hello".toUpperCase() → "HELLO" |
toLowerCase() |
转小写 |
"Hello".toLowerCase() → "hello" |
trim() |
去除首尾空格 |
" Hello ".trim() → "Hello" |
replace(char old, char new) |
字符替换 |
"Hello".replace('l','L') → "HeLLo" |
replace(String old, String new) |
字符串替换 |
"Hello".replace("ll","LL") → "HeLLo" |
split(String regex) |
字符串分割 |
"a,b,c".split(",") → ["a","b","c"] |
startsWith(String prefix) |
判断前缀 |
"Hello".startsWith("He") → true |
endsWith(String suffix) |
判断后缀 |
"Hello".endsWith("lo") → true |
contains(CharSequence s) |
包含判断 |
"Hello".contains("ell") → true |
StringBuffer/StringBuilder 常用方法
方法 |
说明 |
示例 |
append(Object obj) |
追加内容 |
sb.append("World") |
insert(int offset, Object obj) |
插入内容 |
sb.insert(5, " ") |
delete(int start, int end) |
删除子串 |
sb.delete(5, 10) |
deleteCharAt(int index) |
删除字符 |
sb.deleteCharAt(5) |
replace(int start, int end, String str) |
替换子串 |
sb.replace(0, 5, "Hi") |
reverse() |
反转字符串 |
sb.reverse() |
setCharAt(int index, char ch) |
设置字符 |
sb.setCharAt(0, 'h') |
length() |
获取长度 |
sb.length() |
capacity() |
获取容量 |
sb.capacity() |
charAt(int index) |
获取字符 |
sb.charAt(0) |
indexOf(String str) |
查找子串 |
sb.indexOf("World") |
substring(int start) |
截取子串 |
sb.substring(5) |
substring(int start, int end) |
截取子串 |
sb.substring(0, 5) |
toString() |
转为String |
sb.toString() |
性能对比与选择策略
性能对比(10万次拼接)
- String: 约1200ms
- StringBuffer: 约90ms
- StringBuilder: 约60ms
选择策略
- String: 字符串常量、配置文件读取、少量字符串操作
- StringBuffer: 多线程环境下的日志记录、并发字符串处理
- StringBuilder: 单线程下的JSON/XML构建、大量字符串拼接、CSV导出
注意事项
- String的不可变性使其线程安全,但频繁修改会带来性能问题
- StringBuffer的线程安全通过
synchronized
实现,有性能开销
- StringBuilder在单线程环境下性能最优,但多线程下需要手动同步
- 现代编译器会对字符串常量拼接进行优化,但动态拼接仍需手动使用StringBuilder