MST
星途 面试题库

面试题:Java中String、StringBuffer、StringBuilder在性能上的区别

在Java字符串处理中,常常需要在String、StringBuffer、StringBuilder三者之间做选择。请阐述这三者在性能方面,尤其是频繁字符串拼接场景下的具体区别。
43.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

性能区别

  1. String
    • 原理:String类是不可变类,一旦创建,其值就不能被改变。每次对String进行拼接操作时,都会创建一个新的String对象。例如:
    String str = "a";
    str = str + "b";
    
    这里实际上是先创建了一个包含“a”的String对象,然后在拼接“b”时,又创建了一个新的包含“ab”的String对象,原来的“a”对象就成为了垃圾对象等待垃圾回收。
    • 性能:在频繁字符串拼接场景下,由于每次拼接都会创建新对象,开销很大,性能较差。因为频繁创建和销毁对象会增加内存开销和垃圾回收的压力。
  2. StringBuffer
    • 原理:StringBuffer类是可变类,它的对象可以被多次修改,而不产生新的未使用对象。它内部维护了一个字符数组,初始容量为16个字符,如果字符数组满了,会进行扩容。例如:
    StringBuffer sb = new StringBuffer("a");
    sb.append("b");
    
    这里通过append方法直接在原有的StringBuffer对象上进行操作,不会创建新的对象。
    • 性能:在频繁字符串拼接场景下,性能比String好很多,因为它避免了频繁创建新对象。但是,由于它的方法大多是同步的(使用synchronized关键字修饰),以保证线程安全,所以在单线程环境下,这种同步机制会带来一些性能损耗。
  3. StringBuilder
    • 原理:与StringBuffer类似,也是可变类,同样通过维护一个字符数组来实现字符串的动态修改。例如:
    StringBuilder sb = new StringBuilder("a");
    sb.append("b");
    
    也是在原对象上进行操作,不创建新对象。
    • 性能:在频繁字符串拼接场景下,性能最优。因为它与StringBuffer的主要区别在于它的方法不是同步的,在单线程环境下,没有同步带来的额外开销,所以在单线程频繁字符串拼接场景下,它的性能要优于StringBuffer。在多线程环境下,如果需要保证线程安全,就不能使用StringBuilder,而要使用StringBuffer。

综上所述,在频繁字符串拼接场景下,如果是单线程环境,优先选择StringBuilder;如果是多线程环境,优先选择StringBuffer;而String由于性能问题,不适合频繁拼接场景。