String、StringBuiler、StringBuffer,谁性能最高?

共 1202字,需浏览 3分钟

 ·

2020-11-07 05:29

点击“开发者技术前线”,选择“星标?”

让一部分开发者看到未来

作者:Yuchao Huang

来源:www.cnblogs.com/misterchaos/p/12782986.html


一、前言

刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼。

相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己手动去复制数组,非常麻烦,更别提其他复杂操作。

而Java通过String类让字符串操作变得十分简单和方便。除此之外,还有stringbuilder等这些类的辅助,那么本文就String,StringBuiler和StringBuffer的区别开始,去探讨Java中的字符串操作

二、String,StringBuiler和StringBuffer

2.1 String类

Java 提供了 String 类来创建和操作字符串。关注公众号Java技术栈回复面试获取系列面试题。

在源码中可以看到,String类内部的实现也是一个字节数组,这个数组是final类型的,因此String是不可变的对象,每次在对String类进行改变的时候都会生成一个新的string对象,然后将指针指向新的string对象。

推荐阅读《5 个刁钻的 String 面试题!

2.2 StringBuiler 类

和 String 类不同的是,StringBuilder 类的对象能够被多次的修改,并且不产生新的对象

这个特性的意义在于,如果我们进行大量的字符串操作,使用String类就会产生很大的性能消耗,而StringBuilder就可以避免这个问题。

2.3 StringBuffer 类

StringBuffer 和StringBuiler之间的最大不同在于 StringBuilder 的方法不是线程安全的

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

2.4 String,StringBuiler和StringBuffer的比较(对比C/C++)


三、各种字符串操作的效率测试

3.1 测试代码

@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 耗时:"+ getRunTime(startTime));

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

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

}

3.2 测试结果

执行100000次  String 耗时:32s
执行100000次  StringBuilder 耗时:2ms
执行100000次  StringBuffer 耗时:4ms

3.3 小结

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

四、Java字符串和正则表达式

4.1 测试代码

@Test
public void test0(){
    //邮政编码
    String postCode = "[1-9]\\d{5}";
    //区号-座机号码
    String areaCode = "\\d{3}-\\d{8}|\\d{4}-\\d{7}";
    //手机号码
    String phone = "(?:13\\d|15\\d|18\\d)\\d{5}(\\d{3}|\\*{3})";

    String text = "邮政编码:440834"+
                  "区号-座机号码: 020-12345678"+
                  "手机号:13536373839"+
                  "邮政编码:440833"+
                  "区号-座机号码: 010-12345678"+
                  "手机号:13536373739";

    Pattern p = Pattern.compile(postCode);
    Matcher m = p.matcher(text);
    System.out.println("文本中包含邮政编码:");
    while (m.find()){
        System.out.println(m.group());
    }

    p = Pattern.compile(areaCode);
    m= p.matcher(text);
    System.out.println("文本中包含区号-座机号码:");
    while (m.find()){
        System.out.println(m.group());
    }

    p = Pattern.compile(phone);
    m= p.matcher(text);
    System.out.println("文本中包含手机号:");
    while (m.find()){
        System.out.println(m.group());
    }
}

4.2 测试结果

文本中包含邮政编码:
440834
123456
135363
440833
123456
135363
文本中包含区号-座机号码:
020-12345678
010-12345678
文本中包含手机号:
13536373839
13536373739

五、总结

经过测试和比较,可以看到Java中同为字符串操作,但由于背后实现的原理不同,形成的性能差异也是十分巨大,相比之下,C/C++中的字符串操作性能更高。

String类的性能远低于StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的性能稍微高一点。对性能的探究,最终还是要回到使用场景。

可以总结得出,如果不涉及字符串操作,那么String类是首选,如果涉及的字符串操作没有线程安全问题,那么使用StringBuilder,如果涉及的字符串操作存在线程安全问题,那么使用StringBuffer



分享一套面试面试资料及技术好文精选文档都整理到网盘了。

Java面试官手册需要关注下面公众号
回复“面试官手册免费领取


END


后台回复“电子书” “资料” 领取一份干货,数百面试手册等你
开发者技术前线 ,汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。
好文点个在看吧!
浏览 28
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报