String、StringBuilder和StringBuffer是三个不同的类
在电脑磁盘的磁道中有许多的磁颗粒,用来存储数据,像byte、short、int、long等等数据类型都会存储在磁颗粒的页中,一页可占4kB、8KB、12KB、16KB、20KB等等字节,它们的区别是一页占用的字节越大读取的速率越快但缺点是浪费、而每页字节越小读取速率就会越慢,因为磁盘的读取速度大概是一圈5ms(在计算机组成原理中磁盘读取的数据会传入内存中,内存再传给CPU,磁盘不直接传给CPU是因为CPU计算速度在0.2~0.3ns之间他俩速度差距太大,而内存的读取速度大概在15~20ns之间所以会在让CPU运行前先从磁盘放入内存中让它进行等待,这样就不会造成等待时间过长),所以需要进行折中处理,让它既可以读取快并不造成浪费。
int a=1;
在磁盘中会占用一页的空间,如果再让它int b=b;同样会用另一页存储,所以同样的String在磁盘存储时
String a=new String("a");//会在一页开辟新空间
a+="b";//字符串拼接会再使用一页而不是在开始页直接拼接放入,就造成资源浪费效率降低
而StringBuilder和 StringBuffer不是这样它用到了数组存储的方式char []={};
用数组在页中拼接a+="b";时会放在同一页中而不是再用另一页进行存储,直到这一页存不下时才会再用另一页存储(它们都会转化为字节码形式因为存储都是用的字节),这样就不会浪费资源同样效率也会提高
StringBulider是线程不安全的也就是多线程的(线程不安全是当多个线程同时执行时不会按照顺序执行会造成数据的丢失,因为线程不安全所以在多线程用它时需要加入锁来保证线程安全),它的速度是最快的
StringBuffer是线程安全的也就是单线程的,它比StringBulider速度慢
我们用for循环拼接字符串来比较它们三者运行的时间差从而得出他们之间的效率
代码如下:
public class Teststring {
public static void main(String[] args) {
String str=new String("000");
long start=System.currentTimeMillis();//获取拼接前ms的时间戳
for(int i=0;i<10000;i++) {
str+="第"+i;
}
long end=System.currentTimeMillis();//获取拼接后ms的时间戳
long s=end-start;
System.out.println("string需要"+s+"ms");
StringBuilder str1=new StringBuilder("000");
long start1=System.currentTimeMillis();
for(int i=0;i<10000;i++) {
str1.append("第"+i);
}
long end1=System.currentTimeMillis();
long s1=end1-start1;
System.out.println("stringbuilder需要"+s1+"ms");
StringBuffer str2=new StringBuffer("000");
long start2=System.currentTimeMillis();
for(int i=0;i<10000;i++) {
str2.append("第"+i);
}
long end2=System.currentTimeMillis();
long s2=end2-start2;
System.out.println("StringBuffer需要"+s2+"ms");
}
}
运行结果如图:
所以就得出结论:在万级拼接时String的运行效率是最低的,stringbuilder是最快的
而百万级就更别说了,运行如下代码:
public class Teststring {
public static void main(String[] args) {
String str=new String("000");
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++) {
str+="第"+i;
}
long end=System.currentTimeMillis();
long s=end-start;
System.out.println("string需要"+s+"ms");
StringBuilder str1=new StringBuilder("000");
long start1=System.currentTimeMillis();
for(int i=0;i<10000;i++) {
str1.append("第"+i);
}
long end1=System.currentTimeMillis();
long s1=end1-start1;
System.out.println("stringbuilder需要"+s1+"ms");
}
}
结果如图:
我们发现string运行了大概50分钟而stringbuilder仅仅用了52ms,我们这就可以看出string、stringbuilder和stringbuffer之间的效率关系了。