String、StringBuilder、StringBuffer

像会永生那样去学习,像明天就要死亡那样去生活。
——圣雄甘地

String

Java提供了String类来创建和操作字符串。在二进制中可以看到,String类内部的实现也是一个字节数组,这个数组是final类型的,因此String是不可变的对象,每次在对字符串类进行改变的时候都会生成一个新的字符串对象,然后将指针指向新的字符串对象。

StringBuilder

和String类不同的是,StringBuilder类的对象能够被多次修改,并且不产生新的对象。这个特性的意义在于,如果我们进行大量的字符串操作,使用字符串类就会产生很大的性能消耗,而StringBuilder就可以避免这个问题。

StringBuffer

StringBuffer和StringBuiler之间的最大不同在于StringBuilder的方法不是线程安全的。
由于StringBuilder相比较于StringBuffer有速度优势,所以多数情况下建议使StringBuilder类。而在应用程序中要求线程安全的情况下,则必须使用StringBuffer类。

对比项 String StringBuilder StringBuffer
可变性 不可变(Immutable) 可变(Mutable) 可变(Mutable)
线程安全 线程安全(天然不可变) 非线程安全(不同步) 线程安全(同步方法)
性能 低(频繁修改产生新对象) 高(非同步,速度快) 中等(同步带来额外开销)
适用场景 字符串常量、少量拼接 单线程下大量字符串操作 多线程下大量字符串操作
存储方式 字符串常量池 堆内存 堆内存
继承关系 实现CharSequence 继承AbstractStringBuilder 继承AbstractStringBuilder
方法同步 - 无同步 关键方法加synchronized
JDK版本 1.0 1.5 1.0
  1. 可变性:String每次修改都生成新对象,StringBuilder/Buffer直接修改内部char数组
  2. 线程安全:StringBuffer通过synchronized保证线程安全,Builder不保证
  3. 性能排序:StringBuilder > StringBuffer > String(在频繁修改场景)
  4. 版本差异:StringBuilder是JDK1.5优化的非线程安全版本

String,StringBuilder和StringBuffer的比较各种字符串操作的效率测试

测试代码

@Test
public void test() {
    int count = 100000;
    long startTime = System.currentTimeMillis();
    String str = "";
    for (int i = 0; i < count; i++) {
        str += i;
    }
    System.out.println("执行" + count + "次  String 耗时:" + (System.currentTimeMillis() - startTime));

startTime = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < count; i++) {
    stringBuilder.append(i);
}
System.out.println("执行" + count + "次  StringBuilder 耗时:" + (System.currentTimeMillis() - startTime));

startTime = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < count; i++) {
    stringBuffer.append(i);
}
System.out.println("执行" + count + "次  StringBuffer 耗时:" + (System.currentTimeMillis() - startTime));



测试结果

执行100000次  String 耗时:20005
执行100000次  StringBuilder 耗时:1
执行100000次  StringBuffer 耗时:3

可以看到String类的性能远低于StringBuiler和StringBuffer,而StringBuiler在本次测试中比Stringbuffer提高了50%的性能

总结
如果不涉及串联操作,那么String类是首选,如果涉及的串行操作没有线程安全问题,那么使用StringBuilder,如果涉及的串行操作存在线程安全问题,那么使用StringBuffer。

posted @ 2025-03-27 14:53  Tsukinor  阅读(42)  评论(0)    收藏  举报