String、StringBuilder、StringBuffer,谁性能最高?
总阅读量:343次
摘要: 原创出处 cnblogs.com/misterchaos/p/12782986.html 「Yuchao Huang」欢迎转载,保留摘要,谢谢!
一、前言
刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼。相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己手动去复制数组,非常麻烦,更别提其他复杂操作,而Java通过String类让字符串操作变得十分简单和方便。除此之外,还有stringbuilder等这些类的辅助,那么本文就从String,StringBuiler和StringBuffer的区别开始,去探讨Java中的字符串操作。
二、String,StringBuiler和StringBuffer
2.1 String类
Java 提供了 String 类来创建和操作字符串。在源码中可以看到**,String类内部的实现也是一个字节数组**,这个数组是final类型的,因此**String是不可变的对象,每次在对String类进行改变的时候都会生成一个新的string对象,**然后将指针指向新的string对象。
2.2 StringBuilder 类
和 String 类不同的是,StringBuilder 类的对象能够被多次的修改,并且不产生新的对象。这个特性的意义在于,如果我们进行大量的字符串操作,使用String类就会产生很大的性能消耗,而StringBuilder就可以避免这个问题。
2.3 StringBuffer 类
StringBuffer 和StringBuiler之间的最大不同在于 StringBuilder 的方法不是线程安全的。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
2.4 String,StringBuilder和StringBuffer的比较(对比C/C++)
操作类型 | 说明 | 是否可变 | 线程安全性 | 性能 |
---|---|---|---|---|
Java中的String | String 类中使用 final 关键字修饰字符数组来保存字符串 | 不可变 | 线程安全 | 低 |
Java中的StringBuffer | 字符串变量 | 可变 | 线程安全 | 一般 |
Java中的StringBuilder | 字符串变量 | 可变 | 线程不安全 | 一般 |
C/C++ 中的char* 操作 | char *是一个指针,可以 指向一个字符串数组 | 可变 | 不可知 | 高 |
C/C++中的char数组 | 用一个字符数组来保存字符串 | 不可变 | 不可知 | 高 |
C/C++中的String封装类 | string可以被看成是以字符 为元素的一种容器。 | 可变 | 并发读操作 是线程安全的 | 较高 |
三、各种字符串操作的效率测试
3.1 测试代码
|
3.2 测试结果
执行100000次 String 耗时:32s |
3.3 小结
可以看到String类的性能远低于StringBuiler和StringBuffer,而StringBuiler在本次测试中比Stringbuffer提高了50%的性能
四、Java字符串和正则表达式
4.1 测试代码
|
4.2 测试结果
文本中包含邮政编码: |
五、总结
经过测试和比较,可以看到Java中同为字符串操作,但由于背后实现的原理不同,形成的性能差异也是十分巨大,相比之下,C/C++中的字符串操作性能更高。String类的性能远低于StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的性能稍微高一点。对性能的探究,最终还是要回到使用场景,可以总结得出,如果不涉及字符串操作,那么String类是首选,如果涉及的字符串操作没有线程安全问题,那么使用StringBuilder,如果涉及的字符串操作存在线程安全问题,那么使用StringBuffer