先来看看三者的概念区别:
- String 是字符常量,所以一旦创建对象,对象中存放的字符串是不能修改的,对该对象的任何操作都会通过复制创建一个新的字符串对象。
- StringBuffer是字符串可变量,是线程安全的,通过查看源码(java安装目录的src.zip即为源码文件)可发现它的每个方法前面都添加了"synchronized"关键字,说明它是线程安全的。
- StringBuilder 字符串可变量,其实是StringBuffer的单线程等价类。它是在JDK 5才开始加入的。
StringBuilder是单线程的,不涉及线程安全,应该比StringBuffer要快。而如果操作不频繁时String应该比StringBuffer快,因为省去建立对象的开销。
那么实际情况是怎么样的呢?我们通过测试来看结果:
public class Main { public static void main(String[] args) { int loopcount=1000; testString(loopcount); testStringBuffer(loopcount); testStringBuilder(loopcount); } static void testString(int loopcount){ long startTime=System.nanoTime();//毫微秒 String temp=""; for(int i=0;i<loopcount;i++){ temp+=i; } long endTime=System.nanoTime(); System.out.println("testString花费的时间:"+(endTime-startTime)); } static void testStringBuffer(int loopcount){ long startTime=System.nanoTime(); StringBuffer temp=new StringBuffer(""); for(int i=0;i<loopcount;i++){ temp.append(i); } long endTime=System.nanoTime(); System.out.println("testStringBuffer花费的时间:"+(endTime-startTime)); } static void testStringBuilder(int loopcount){ long startTime=System.nanoTime(); StringBuilder temp=new StringBuilder(""); for(int i=0;i<loopcount;i++){ temp.append(i); } long endTime=System.nanoTime(); System.out.println("testStringBuilder花费的时间:"+(endTime-startTime)); } }
代码中把循环次数设置为1000,执行结果:
testString花费的时间:13980087
testStringBuffer花费的时间:559936
testStringBuilder花费的时间:310430
从中可以看到 StringBuilder的确是最快的,那么现在把循环次数降低到极限:1次,设置loopcount=1。执行结果:
testString花费的时间:115117
testStringBuffer花费的时间:581481
testStringBuilder花费的时间:4938
看到还是StringBuilder最快的。
得出结论:
- String在三个中是最耗时的,但写法方便;
- StringBuilder最快,但不支持多线程;
-
StringBuffer居中但如果用于多线程,最好使用StringBuffer安全;