在平常的开发中,很多人喜欢使用String这个类来定义一些字符串,而且创建的很多,个人感觉不是很适合。
String:一个final类,是不可变的,重新赋值时,会返回一个新的对象
StringBuffer:是字符串变量,它的内容是可以进行修改的,而且还是线程安全的
StringBuilder:和StringBuffer基本上差不多,但是是线程不安全的,所以单线程的情况下,性能快于StringBuffer
对比性能:
String的内容是不可以改变的,当我们创建一个对象后,在会先在栈内存中进行查找,看看是否存在相同的,如果存在,那么不再继续创建,直接引用就可以了,否则需要单独创建一个。
所以性能上会存在问题,当我们在一个循环中多次对String进行赋值的时候,而且每次的值都不一样,那么系统会创建多个对象,这样虚拟机的内存很快就会被占用完毕,从而导致内存溢出。
通过下面的例子来观看两者的运行速度
同样循环50000次来修改字符串值,最后输出前后时间,为了避免多线程获取cpu的时间不一定,所以采用单线程来进行
package com.jacksoft.string;
import java.util.Date;
/**
* 测试String和StringBuffer
* @author Jack
*
*/
public class StringAndStringBufferTest {
public static void main(String[] args) {
testString(50000);
testStringBuffer(50000);
}
private static void testString(int count){
System.out.println("String 开始秒:" + new Date().getSeconds());
String testStr = "";
for(int i = 0; i < count ; i++){
testStr += i;
}
System.out.println("String 结束秒:" + new Date().getSeconds());
}
private static void testStringBuffer(int count){
System.out.println("StringBuffer 开始秒:" + new Date().getSeconds());
StringBuilder testSb = new StringBuilder("");
for(int i = 0; i < count ; i++){
testSb.append(i);
}
System.out.println("StringBuffer 结束秒:" + new Date().getSeconds());
}
}
得到的结果如下:
String 开始秒:14
String 结束秒:30
StringBuffer 开始秒:30
StringBuffer 结束秒:30
同样是循环5w次,但是String花费了16秒,所以性能上次于StringBuffer