Java字符串处理终极指南:String、StringBuilder与StringBuffer
一、String类全面解析
1. 基础特性与内存机制
- 不可变性原理:内部使用final char[]存储数据
- 字符串常量池:JVM维护的特殊存储区域
- 内存布局示例:
String s1 = "hello"; // 常量池String s2 = new String("hello"); // 堆内存String s3 = s2.intern(); // 返回常量池引用
2. 完整API详解
构造方法全集
// 空字符串构造
String empty = new String();// 字节数组构造
byte[] bytes = {104, 101, 108, 108, 111};
String fromBytes = new String(bytes, StandardCharsets.UTF_8);// 字符数组构造
char[] chars = {'h','e','l','l','o'};
String fromChars = new String(chars, 1, 3); // "ell"// 字符串缓冲构造
StringBuffer sb = new StringBuffer("buffer");
String fromBuffer = new String(sb);
查询方法全集
String sample = "Hello Java";// 基础查询
int len = sample.length(); // 10
char ch = sample.charAt(4); // 'o'
int code = sample.codePointAt(4); // 111// 比较方法
boolean eq = sample.equals("hello java"); // false
boolean eqIC = sample.equalsIgnoreCase("hello java"); // true
int cmp = sample.compareTo("Hello"); // 5// 搜索方法
int idx1 = sample.indexOf('a'); // 7
int idx2 = sample.indexOf("Java"); // 6
int idx3 = sample.lastIndexOf('a'); // 9
修改方法全集
String original = "Java";// 拼接
String concated = original.concat("8"); // "Java8"// 替换
String replaced1 = original.replace('a', 'A'); // "JAvA"
String replaced2 = original.replaceAll("a", "A"); // "JAvA"
String replaced3 = original.replaceFirst("a", "A"); // "JAva"// 大小写
String upper = original.toUpperCase(); // "JAVA"
String lower = original.toLowerCase(); // "java"// 子串
String sub1 = original.substring(1); // "ava"
String sub2 = original.substring(1,3); // "av"// 去除空格
String spaced = " Java ";
String trimmed = spaced.trim(); // "Java"
String stripped = spaced.strip(); // "Java" (Java 11+)
二、StringBuilder深度剖析
1. 内部实现原理
- 动态数组:初始容量16,自动扩容(2n+2)
- 关键字段:
char[] value; // 存储字符int count; // 实际字符数
2. 完整API手册
构造方法
StringBuilder sb1 = new StringBuilder(); // 容量16
StringBuilder sb2 = new StringBuilder(100); // 指定容量
StringBuilder sb3 = new StringBuilder("Init"); // 初始值+16
修改操作
StringBuilder sb = new StringBuilder("Hello");// 追加
sb.append(" World"); // 支持所有基本类型
sb.appendCodePoint(65); // 追加Unicode字符'A'// 插入
sb.insert(5, ","); // 在索引5处插入
sb.insert(5, 123); // 插入数字// 删除
sb.delete(5, 8); // 删除索引5-7
sb.deleteCharAt(5); // 删除单个字符// 替换
sb.replace(5, 10, "Java"); // 替换指定区间
sb.setCharAt(1, 'E'); // 替换单个字符// 容量管理
sb.ensureCapacity(200); // 确保最小容量
sb.trimToSize(); // 缩容到实际大小
查询操作
int len = sb.length(); // 当前长度
int cap = sb.capacity(); // 当前容量
char c = sb.charAt(2); // 获取字符
String sub = sb.substring(1, 4); // 获取子串
三、StringBuffer全面解析
1. 线程安全实现
- 同步机制:所有方法使用synchronized修饰
- 性能影响:比StringBuilder慢20-30%
2. 完整API参考
StringBuffer sbf = new StringBuffer("Thread");// 追加(线程安全)
sbf.append(" Safe").append(1.0);// 插入(线程安全)
sbf.insert(6, "ing-");// 其他方法与StringBuilder一致
sbf.replace(0, 6, "Process");
sbf.delete(7, 12);
sbf.reverse();
四、三者的深度对比
1. 性能基准测试
// 测试代码示例
long start = System.nanoTime();
String result = "";
for(int i=0; i<100000; i++) {result += i; // String拼接
}
long stringTime = System.nanoTime() - start;start = System.nanoTime();
StringBuilder sb = new StringBuilder();
for(int i=0; i<100000; i++) {sb.append(i);
}
long builderTime = System.nanoTime() - start;// 典型结果(纳秒):
// String: 5000000
// StringBuilder: 100000
// StringBuffer: 150000
2. 内存使用分析
类型 | 内存特点 | 适用场景 |
---|---|---|
String | 产生大量临时对象 | 静态字符串、常量 |
StringBuilder | 单对象操作,内存利用率高 | 单线程字符串构建 |
StringBuffer | 同步开销带来额外内存消耗 | 多线程环境字符串构建 |
3. 线程安全对比
// StringBuffer的线程安全实现示例
public synchronized StringBuffer append(String str) {toStringCache = null;super.append(str);return this;
}
五、高级应用场景
1. 超大文本处理
// 使用StringBuilder处理MB级文本
StringBuilder hugeText = new StringBuilder(10_000_000);
try(BufferedReader br = new BufferedReader(new FileReader("big.txt"))) {String line;while((line = br.readLine()) != null) {hugeText.append(line).append("\n");}
}
2. 正则表达式高效处理
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);
StringBuilder numbers = new StringBuilder();
while(matcher.find()) {numbers.append(matcher.group()).append(",");
}
3. 复杂字符串构建
StringBuilder sql = new StringBuilder(256);
sql.append("SELECT * FROM users").append(" WHERE age > ").append(minAge).append(" AND name LIKE '").append(namePattern).append("'").append(" ORDER BY ").append(sortField);
六、最佳实践总结
1. 性能优化技巧
-
预设容量:根据最终大小初始化StringBuilder
StringBuilder sb = new StringBuilder(estimatedLength);
-
批量操作:减少方法调用次数
sb.append("Name:").append(name).append(", Age:").append(age);
-
避免链式toString:
// 不好String result = new StringBuilder().append(a).append(b).toString();// 更好StringBuilder sb = new StringBuilder();sb.append(a);sb.append(b);String result = sb.toString();
2. 线程安全方案
// 方案1:使用StringBuffer
StringBuffer safeBuffer = new StringBuffer();// 方案2:包装StringBuilder
StringBuilder builder = new StringBuilder();
Object lock = new Object();synchronized(lock) {builder.append(threadSafeData);
}
3. 常见陷阱规避
- 字符串拼接陷阱:
// 错误示范(产生大量临时对象)for(String item : list) {result += item;}// 正确做法StringBuilder sb = new StringBuilder();for(String item : list) {sb.append(item);}
- 编码问题:
// 指定字符集处理字节String fromBytes = new String(bytes, "UTF-8");
七、API速查手册
String核心方法速查
charAt()
, codePointAt()
, compareTo()
,
concat()
, contains()
, contentEquals()
,
endsWith()
, equals()
, equalsIgnoreCase()
,
format()
, getBytes()
, indexOf()
,
intern()
, isEmpty()
, isBlank()
,
join()
, lastIndexOf()
, length()
,
matches()
, replace()
, replaceAll()
,
replaceFirst()
, split()
, startsWith()
,
substring()
, toCharArray()
, toLowerCase()
,
toString()
, toUpperCase()
, trim()
,
valueOf()
, strip()
, repeat()
StringBuilder/StringBuffer方法速查
append()
, capacity()
, charAt()
,
delete()
, deleteCharAt()
, ensureCapacity()
,
getChars()
, indexOf()
, insert()
,
lastIndexOf()
, length()
, replace()
,
reverse()
, setCharAt()
, setLength()
,
subSequence()
, substring()
, toString()
,
trimToSize()
, appendCodePoint()
, codePointAt()
# Java字符串处理终极指南:String、StringBuilder与StringBuffer