String和StringBuffer
String 的值不可变,每次操作都会生成新对象,既慢又费内存。
StringBuffer 同样表示字符串,但内部实现不同:修改时尽量在原缓冲区上动手,不急着造新对象,内存上通常优于 String。
StringBuffer 默认分配 16 个字符的缓冲区,内容超出时自动扩容,而不是每次都换一个全新对象。它不像 String 那样支持字面量简写,只能 new:
一、StringBuffer 常用方法
方法偏重追加、插入、删除。实际开发里如果要对同一段内容频繁改动,优先用 StringBuffer(单线程可改用 StringBuilder)。
1)append()
append() 往当前内容末尾追加,调用后对象本身变了,不是换了一个引用:
字符串的 + 在编译期会转成可变缓冲再 append(),最后 toString()。早期 javac 用的是 StringBuffer,较新的编译器多用 StringBuilder。循环里反复 str += fragment 仍会不断产生中间 String,效率远差于自己持有一个 Buffer。短字符串用 + 更直观,可以稍微牺牲效率换可读性。
2)deleteCharAt() / delete()
3)insert()
在指定位置插入,可以看成 append 的升级版。索引 3 是 'd' 前面,所以插入后是 abcxyzdef(原文写成 abcdxyzef,位置算错了):
4)setCharAt()
以上只是常用方法,完整列表看 API 文档。
二、效率对比
把 26 个英文字母拼接 10000 次,差异会非常明显:
叠加 30000 次时,原文测到 String 约 35923ms、StringBuffer 约 8ms。次数越多,差距越大。大量拼接请用 Buffer / Builder。
三、StringBuilder 与选型
StringBuilder 和 StringBuffer 功能、方法几乎一样:Buffer 线程安全,Builder 非线程安全,单线程时 Builder 略快。三者都实现了 CharSequence(length()、charAt、subSequence)。String 直接实现该接口;Builder 和 Buffer 都是可变序列,继承 AbstractStringBuilder。
| 类型 | 可变 | 线程安全 | 适用 |
|---|---|---|---|
| String | 否 | 是(不可变本身安全) | 少量数据、字面量 |
| StringBuilder | 是 | 否 | 单线程大量拼接(通常最快) |
| StringBuffer | 是 | 是 | 多线程大量拼接 |
速度大致是 StringBuilder > StringBuffer > String,这是相对值,不是绝对定律。
一句话总结:少量用 String;单线程大量改用 StringBuilder;多线程大量改用 StringBuffer。
转载请注明来源:String和StringBuffer本文链接地址:https://ai.zhousir.top/?p=56






