首页
学习
活动
专区
圈层
工具
发布

String和StringBuilder、StringBuffer的区别?

说真的,这个问题我还真是经常被问,特别是坐电梯的时候突然被同事cue,“你说说String和StringBuilder、StringBuffer到底有啥区别啊?”。我说你等我喘口气,刚刚还在群里吐槽bug呢,行吧,那我随便唠两句,别太当真哈。

昨晚加班到十一点半,眼睛都快花了,优化我们那个批量处理的代码。刚好碰到一个同事在用+拼接字符串,脑瓜子嗡嗡的,他说用StringBuilder会不会好点。我说这个你得明白String、StringBuilder还有个StringBuffer,光看名字就知道是一家子的,但是脾气可差老远。

首先String,大家平时写Java都用,String s = "hello";这种很常见吧。它有个最大特点,就是“不可变”,就是你每次改内容其实是new了一个新的对象,比如这样:

String a = "hello";

a = a + " world";

System.out.println(a); // 结果是hello world

你以为a变了,其实是new了一个新的String,原来的"hello"还在内存里躺着。所以你要是for循环里一直拼接字符串,用String,老铁那内存分分钟教你做人,GC都看不下去,频繁new对象。

StringBuilder——单线程的拼接狂魔

然后就有聪明人搞出来StringBuilder,这个家伙是个“可变对象”,它内部其实就是个char数组,有个length,append的时候直接往后塞,不new新对象。举个栗子:

StringBuilder sb = new StringBuilder();

sb.append("hello");

sb.append(" world");

System.out.println(sb.toString()); // hello world

每次append都不会new新的对象,效率嗖嗖的,拼接字符串首选啊。缺点就是它不是线程安全的,多线程里别用它,不然容易数据乱套。

StringBuffer——老派线程安全选手

再说StringBuffer,这货历史悠久,Java早期就有,和StringBuilder用法差不多,也是append啥的,但所有方法都加了synchronized,所以它线程安全,多个线程一起用不会乱,但相应地效率没StringBuilder高,锁嘛,有点性能损耗:

StringBuffer sbf = new StringBuffer();

sbf.append("hello");

sbf.append(" world");

System.out.println(sbf.toString()); // hello world

但现在一般项目里,除非有特殊要求,基本很少用它了,都推崇用StringBuilder加外部同步。

我们组那个小李,for循环里还在傻傻用String拼接,我都无语了,改成StringBuilder,性能立马就上去了。你们要是遇到频繁字符串拼接的,记住:

单线程用StringBuilder

多线程(极少)用StringBuffer,或者自己加锁+StringBuilder

真没事干才用String+拼接,偶尔几次无所谓,量大了就完蛋

还有一个小tips哈,JDK8之后,编译器会自动优化一些String拼接,比如String s = "a" + "b" + "c";会在编译期就算好,所以写死的还能凑合,动态拼接的时候就别折腾了。

哦对,刚才群里还有人问,StringBuilder和StringBuffer能不能互相转?其实没啥必要,都是toString()转String就行,想线程安全就老老实实自己加锁。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OcX0NS6_0XdJNwck4L7b9CCQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券