悠悠楠杉
Java字符串操作指南:拼接与截取的核心方法
一、字符串拼接的4种实战方案
1. 加号运算符的隐藏成本
java
String str1 = "Hello";
String str2 = "World";
String result = str1 + ", " + str2; // 编译后实际使用StringBuilder
看似简单的加号操作,在循环中会产生严重性能问题:
java
// 反例:每次循环都创建新StringBuilder
String output = "";
for(int i=0; i<1000; i++) {
output += i; // 等价于new StringBuilder().append(output).append(i)
}
2. StringBuilder线程不安全但高效
java
StringBuilder builder = new StringBuilder();
builder.append("Java").append(" ");
builder.append(11);
String version = builder.toString(); // "Java 11"
关键特性:
- 初始容量16字符,自动扩容
- 链式调用:builder.append().append()
- 指定初始容量可优化:new StringBuilder(1024)
3. StringBuffer的线程安全方案
java
StringBuffer buffer = new StringBuffer();
buffer.append("多线程");
buffer.insert(0, "安全");
System.out.println(buffer); // "安全多线程"
4. String.join()的优雅语法
java
String[] languages = {"Java", "Python", "Go"};
String joined = String.join("|", languages); // "Java|Python|Go"
二、字符串截取的3个核心技巧
1. substring()方法双版本
java
String text = "Java17";
// JDK6:创建新字符数组
String sub1 = text.substring(1,4); // "ava"
// JDK7+:共享原字符数组(可能内存泄漏)
String sub2 = text.substring(4); // "17"
内存陷阱示例:
java
String bigText = new String(new byte[10_000_000]);
String small = bigText.substring(0,3);
// bigText字符数组仍被small引用无法回收
2. split()正则分割
java
String csv = "A,B,C,D";
String[] parts = csv.split(","); // ["A","B","C","D"]
// 复杂分割案例
String log = "2023-08-20 14:30:00 [ERROR]";
String[] segments = log.split("\s+|\[|\]");
3. 模式匹配提取
java
Pattern pattern = Pattern.compile("(\\d{3})-(\\d{4})");
Matcher matcher = pattern.matcher("电话:010-1234");
if(matcher.find()) {
System.out.println(matcher.group(1)); // "010"
}
三、性能优化关键指标
| 方法 | 10万次耗时(ms) | 内存消耗(MB) |
|--------------------|---------------|-------------|
| 加号拼接 | 2850 | 45.6 |
| StringBuilder | 12 | 1.2 |
| StringBuffer | 15 | 1.3 |
| String.join | 18 | 1.5 |
实战建议:
1. 循环拼接必须使用StringBuilder
2. 已知最终长度时预设容量
3. 多线程环境用StringBuffer
4. 超大字符串截取考虑new String()
四、常见问题解决方案
Q1:如何高效拼接不同类型数据?
java
StringBuilder sb = new StringBuilder();
sb.append("ID:").append(1001) // int
.append(", 激活:").append(true) // boolean
.append(", 价格:").append(9.99); // double
Q2:处理含中文的截取java
String chinese = "中文测试";
// 错误做法:可能截取到半个汉字
String bad = chinese.substring(0,3);
// 正确方案:转为字符数组处理
char[] chars = chinese.toCharArray();
String safe = new String(chars, 0, 3);