欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

String、StringBuilder、StringBuffer到底该使用谁?

程序员文章站 2022-03-09 20:46:50
...

String

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

StringBuilder

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

StringBuffer

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

String,StringBuilder和StringBuffer的比较

操作类型 说明 是否可变 线程安全 表现
String 字符串类中使用final关键字修饰字符数组来保存字符串 不可变 线程安全
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 耗时:20206
执行100000次  StringBuilder 耗时:1
执行100000次  StringBuffer 耗时:3

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

总结

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