String、StringBuilder、StringBuffer:三个"字符串",到底区别在哪?
学 Java 一定会遇到这三兄弟:
String、StringBuilder、StringBuffer。 名字都带"String",用法也差不多,到底区别在哪?拼接字符串又快慢之分? 这篇一篇讲透,不堆术语,用生活场景帮你彻底记住。
一、String:死板的"成品书"
String就是一本已经写好了的已经封了面,无法再更改的书.
想要修改里面的内容,只能舍弃了之前已经印好的书,重新再印一版
java
String s = "你好";
s = s + "世界"; // 不是改,是重新造了一本"你好世界",旧的"你好"被扔掉
特点:
-
不可变,改一次就重造一次
-
是真正的"字符串",日常用字符串操作基本都是它
-
线程安全(没人能偷偷改它),用着放心。
-
频繁改(比如循环拼接)会很浪费,每次都重印新书。
二、StringBuilder:活页本,能续写
StringBuilder 就像一本活页本,想要续写就打开铁环加页进去,不需要重新印.
java
StringBuilder sb = new StringBuilder();
sb.append("你好"); // 第一页
sb.append("世界"); // 接着往下写,同一个本子
String result = sb.toString(); // 写完了,一次性变成 String
特点:
- 可变,
append()直接在原基础上续写,不需要new一个新的 - 拼接次数越多,比
String省得越多 - 线程不安全, 但如果你只是单线程用(绝大多数情况),这完全不是问题
三、StringBuffer:上了锁的活页本
StringBUffer与StringBuilder的用法几乎一模一样,都能续写
java
StringBuffer sb = new StringBuffer();
sb.append("你好");
sb.append("世界");
唯一的区别是这本活页本是上了锁的,线程安全
特点:
- 可变,能续写(和 StringBuilder 一样)
- 线程安全,有锁,因此稍慢一点
- 只有多线程并发同时改同一个字符串时才需要它
四、一张表,看清三兄弟
| String | StringBuilder | StringBuffer | |
|---|---|---|---|
| 能不能改 | 不可变 | 可变 | 可变 |
| 快不快 | 改一次重造一次,慢 | 快 | 稍慢 |
| 线程安全 | 安全 | 不安全 | 安全 |
| 什么时候用 | 日常字符串操作 | 循环拼接主力 | 多线程并发才用 |
六、拼接效率差距(核心重点)
用 String 的 + 拼接:
java
String s = "";
for (int i = 0; i < 10000; i++) {
s = s + "第" + i + "个 "; // 每次都重印新书
}
每次累加都需要,先取出旧值,开辟一个新的空间将旧值与新值拼接成新的字符串,再扔掉旧值
拼接10000次,就造了10000书,扔掉了9999本书,时间肯定很慢
用 StringBuilder:
java
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append("第" + i + "个 "); // 同一个本子,接着写
}
String result = sb.toString();
append() 写完就在书里面加页,不用重印,也不用丢到之前的书
拼接10000次就只用写入10000次,时间肯定很快
用StringBuffer:
java
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < 10000; i++) {
sbf.append("第" + i + "个 ");//与StringBuilder一致
}
String r2 = sbf.toString();
不过多线程状态下,上了锁需要等待,所以慢一点
最后,一句话总结
String 是印死的成品书,改一次重印一次; StringBuilder 是活页本,接着写很快; StringBuffer 是上了锁的活页本,多线程才用它。
日常用 StringBuilder,短的用
+没毛病,多线程才轮到 StringBuffer。