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

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

源码精品专栏

 

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

  • 一,前言

  • 二,字符串,StringBuiler和StringBuffer

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

  • 四,Java字符串和正则表达式

  • 五,总结


一,前言

刚开始学习Java时,作为只是C语言的小白,就为其中的字符串操作而感到震撼。在此之下,C语言在字节序中保存一个结尾的\ 0去表示字符串,想实现串联拼接,还需要调用strcpy库函数或者自己手动去复制副本,非常麻烦,更别提其他复杂操作,而Java通过字符串类让串联操作变得十分简单和方便。此外,还有stringbuilder等这些类的辅助,那么本文就从String,StringBuiler和StringBuffer的区别开始,去探讨Java中的字符串操作。

二,字符串,StringBuiler和StringBuffer

2.1字符串类

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

2.2 StringBuilder类

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

2.3 StringBuffer类

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

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

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

操作类型说明是否可变线程安全性表现
Java中的String字符串类中使用final关键字修饰字符数组来保存字符串不可变线程安全
Java中的StringBuffer字符串变量可变线程安全一般
Java中的StringBuilder字符串变量可变线程不安全一般
C / C ++中的char *操作char *是一个指针,可以指向一个字符串多重可变不可知
C / C ++中的char数组用一个字符编码来保存字符串不可变不可知
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 ++中的串行操作性能更高。类的性能远低于StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的性能稍微高一点。对性能的探究,最终还是要回到使用场景,可以进行总结,如果不涉及串联操作,那么String类是首选,如果涉及的串行操作没有线程安全问题,那么使用StringBuilder,如果涉及的串行操作存在线程安全问题,那么使用StringBuffer



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值