String、StringBuilder、StringBuffer:三个"字符串",到底区别在哪?

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。

相关推荐
Pniubi8 小时前
MySQL靠什么实现事务的?事务隔离级别有哪些?
java·数据库·mysql
一条Go8 小时前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github
Moment8 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
数据库小学妹8 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
松仔log9 小时前
Kotlin中级——callbackFlow
java·前端·kotlin
三小河9 小时前
SWC 凭什么比 Babel 快 ?项目优化迁移踩坑记录
前端·后端
鶴哥只手遮天9 小时前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源
知守观10 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计
文丑颜不良啊10 小时前
LeetCode2541~2560题目解析
java·leetcode
Anymous10 小时前
我手写的 Redis 锁,输给了 10 秒的 TTL
后端·架构