Java中String, StringBuilder, StringBuffer比较

·961·3 分钟·
AI摘要: 本文比较了Java中的String, StringBuilder, StringBuffer三种字符串类,指出它们在性能和线程安全方面的不同。String是不可变的,频繁修改效率低;StringBuilder是线程安全的,但效率较低;StringBuffer既线程安全又高效,但需要加锁。最后,文章还提到了Golang中处理字符串拼接的性能问题,以及与Java的对比。

String

在Java当中,String是一个不可变类(被声明为final class),对String的任何操作都将创建一个全新的String对象,其存放地址在字符串常量池当中。

这样做的好处是线程安全,不同的线程对同一个字符串进行修改的时候,都会创建一个全新的String;缺点是在频繁修改字符串的情况下,效率偏低。

StringBuilder

在频繁对字符串进行增删改的情况中,String的效率偏低,这个时候Java中新增了StringBuilder类(内置了append,add方法),可以原地修改字符串,效率很高,但是也带来的线程不安全的问题。

StringBuffer

StringBufferStringBuilder的区别不大,只是在每个操作方法都加了synchronized同步关键字,所以就是一个线程安全的可修改的字符序列

总结

  • 性能上

    • 线程安全(带锁)— 速度慢

    • 线程不安全(不带锁)— 速度快

  • 使用场景上

    • 操作数量少 — String

    • 单线程大量操作 — StringBuilder

    • 多线程大量操作 — StringBuffer


  • golang对比补充:

    • 最近在学习golang,同样遇到了String拼接的性能问题。Golang和Java一样,String是不可变的,频繁的凭借会创造大量的中间字符串。Golang提供了strings.Builder和Bytes.Buffer两种处理办法,两种方式的底层都是维护了一个动态可变的[]bytes数组。strings.builder会比bytes.Buffer稍微快一点,因为strings.builder直接将[]bytes动态数组转化为字符串,而bytes.Buffer会重新申请一块空间存储转化出来的最终字符串。

    • 在Golang中的bytes.Buffer和Java中的StringBuffer不一样,是没有加锁的

Kaggle学习赛初探