String vs StringBuffer vs StringBuilder

代码实现

String 类是一个final类型的不可变类,所以在对String类进行操作时,都会创建一个新的String类,造成空间和时间的开销。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    }

StringBuilder类 和StringBuffer类均实现了相同的接口和继承了相同的父类,只是StringBuffer的方法上加了synchronized关键字,保证在多线程情况下是线程安全的,其它实现没有差别。

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{
    @Override
    @HotSpotIntrinsicCandidate
    public StringBuilder append(int i) {
        super.append(i);
        return this;
    }
}

StringBuffer类

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{
    @Override
    @HotSpotIntrinsicCandidate
    public synchronized StringBuffer append(int i) {
        toStringCache = null;
        super.append(i);
        return this;
    }
}

性能对比

通过写代码对比,String的性能比StringBuffer和StringBuiler慢5-10个数量级;
在单线程情况下,StringBuffer的性能反而比StringBuilder快,具体原因有待分析;
在多线程情况下,StringBuilder性能比StringBuffer性能快,因为StringBuffer需要获取对象锁;

测试结果为:

StringBuilder cost:14
MultiStringBuffer cost:102
MultiStringBuilder cost:61
StringBuffer cost:9
String cost:940
@TestInstance(Lifecycle.PER_CLASS)
public class GenericTest {

    @Test
    public void testString() {

        AtomicReference<String> s = new AtomicReference<>("");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        IntStream.range(0, 100000).forEach(i -> {
            s.set(s + "i");
        });
        stopWatch.stop();
        System.out.println("String cost:" + stopWatch.getTotalTimeMillis());
    }

    @Test
    public void testStringBuilder() {
        StringBuilder s = new StringBuilder();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        IntStream.range(0, 100000).forEach(i -> {
            s.append(i);
        });
        stopWatch.stop();
        System.out.println("StringBuilder cost:" + stopWatch.getTotalTimeMillis());
    }

    @Test
    public void testStringBuffer() {

        StringBuffer s = new StringBuffer();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        IntStream.range(0, 100000).forEach(i -> {
            s.append(i);
        });
        stopWatch.stop();
        System.out.println("StringBuffer cost:" + stopWatch.getTotalTimeMillis());
    }

    @Test
    public void testMultiStringBuilder() throws InterruptedException {
        StringBuilder s = new StringBuilder();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Thread t1 = new Thread(() -> {
            IntStream.range(0, 100000).forEach(i -> {
                s.append(i);
            });
        });
        Thread t2 = new Thread(() -> {
            IntStream.range(0, 100000).forEach(i -> {
                s.append(i);
            });
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        stopWatch.stop();
        System.out.println("MultiStringBuilder cost:" + stopWatch.getTotalTimeMillis());
    }

    @Test
    public void testMultiStringBuffer() throws InterruptedException {

        StringBuffer s = new StringBuffer();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Thread t1 = new Thread(() -> {
            IntStream.range(0, 100000).forEach(i -> {
                s.append(i);
            });
        });
        Thread t2 = new Thread(() -> {
            IntStream.range(0, 100000).forEach(i -> {
                s.append(i);
            });
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        stopWatch.stop();
        System.out.println("MultiStringBuffer cost:" + stopWatch.getTotalTimeMillis());
    }

}

应用场景

对于少量的字符串拼接,可以采用String;
对于单线程下大量字符串操作,用StringBuffer和StringBuilder均可;
对于多线程下的大量字符串操作,采用StringBuffer;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值