Java 里 String 用得到处都是,但一旦频繁拼接它就露怯,这时候该换 StringBuilder。这篇讲清楚两者的常用方法和怎么选。
String 是不可变的
String s = "hello";
s.toUpperCase(); // 返回新串,s 本身没变
System.out.println(s); // 输出:hello
s = s.toUpperCase(); // 要用变量接住返回值
System.out.println(s); // 输出:HELLO
String 的每个"修改"方法都不改原串,而是返回一个新串。忘了接返回值,后面代码就像什么都没发生过——这是新手最常见的坑。
常用方法速查
String s = "Java 入门";
s.length() // 7,字符数
s.charAt(0) // 'J'
s.contains("入门") // true
s.indexOf("a") // 1,第一次出现的位置
s.substring(5) // "入门",从下标 5 截到结尾
s.replace("Java", "Go") // "Go 入门"
s.trim() // 去掉两端空白
s.split(" ") // ["Java", "入门"]
判断两个字符串相等,千万别用 ==:
String a = new String("hi");
String b = new String("hi");
System.out.println(a == b); // false,比的是内存地址
System.out.println(a.equals(b)); // true,比的是内容
== 判断的是不是同一个对象,字符串比内容一律用 equals()。
拼接频繁时换 StringBuilder
先看反面教材:
String result = "";
for (int i = 1; i <= 1000; i++) {
result += i; // 每轮循环都创建一个新 String,又慢又费内存
}
+= 每一轮都造一个新对象,循环上千次性能明显下降。StringBuilder 在内部字符数组上直接改,攒完一次性转回 String:
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
sb.append(i).append(",");
}
System.out.println(sb.toString()); // 输出:1,2,3,4,5,
常用方法就三个:append() 追加、insert() 在指定位置插入、toString() 转回 String。还有个顺手的 reverse():
System.out.println(new StringBuilder("abc").reverse()); // 输出:cba
到底怎么选
- 固定几段拼一次:直接用
+,简单直观,编译器会自己优化 - 循环里反复拼接:果断换 StringBuilder
- 多线程环境共享的可变字符串(非常少见):才轮到 StringBuffer 出场
一句话总结:写起来舒服用 +,跑起来要快用 StringBuilder。
小结
- String 不可变,所有"修改"方法都返回新串,记得接住返回值
- 比较内容用
equals(),==只比地址 - 循环拼接用
append(),最后toString() - 偶尔拼一次用
+没问题,不必过度优化