String的直接拼接与间接拼接
直接拼接与间接拼接的耗时其实不一定谁多谁少
理论来讲,肯定是直接拼接的字符串耗时短
但是测试发现当数据量非常庞大,如100000时,间接拼接耗时反而更少
有没有大佬可以评论讲一下原因哇???
但是数据量并不多时,如200,测试结果直接拼接明显更快
1.直接拼接
public void directGet(){
String s=" ";
Long start=System.currentTimeMillis();
for (int i=0;i<200;i++){
s+="a"+"b"+"c";
//会直接被优化为abc
}
Long end=System.currentTimeMillis();
System.out.println("String直接拼接字符串用时为:"+(end-start));
}
2.间接拼接
public void indirectGet(){
String s=" ";
String a="a";
String b="b";
String c="c";
Long start=System.currentTimeMillis();
for (int i=0;i<200;i++){
s+=a+b+c;
//依赖对象,不会直接变成“abc”
//而是需要创建StringBuilder类,并调用append方法
//但是如果用final修饰String a/b/c,那么在编译期,符号引用就可以直接被真值所代替
}
Long end=System.currentTimeMillis();
System.out.println("String间接拼接字符串用时为:"+(end-start));
}
3.下边是一些关于字符串本身的一些测试示例
String s0 = "abc";
String s1=new String("abc");
String s2 = "a" + "b" + "c";
String sa="a";
String sb="b";
String sc="c";
final String a="a";
final String b="b";
final String c="c";
String mix1=sa+sb+sc;
String mix2=sa+sb+sc;
String mix3=a+b+c;
System.out.println(s0==s1); //false
System.out.println(s0==s2); //true
//在编译阶段s2会被直接优化为“abc”
System.out.println(mix1==s0); //false
System.out.println(mix1==mix2); //false
// 对象在拼接时是通过new一个StringBuilder对象,然后调用append方法实现的
//mix1与mix2在拼接过程中分别new了两个对象,不相同
//所以mix1==mix2,判断为false
System.out.println(mix3==s0); //true
//mix3中的abc都用真值替代后拼接优化为“abc”
String,StringBuilder,StringBuffer的使用与对比
1.用String,通过s+="a";的方法实现
String s=" ";
Long start=System.currentTimeMillis();
for(int i=0;i<100000;i++){
s+="z"+i;
}
Long end=System.currentTimeMillis();
System.out.println("拼接字符串用时为:"+(end-start));
//输出结果为3121
这种方法的底层其实是在每一次调用s+="z"+i时,都创建一个String Builder对象,然后用该对象调用append方法,完成字符串的拼接
以上述代码为例,拼接过程创建了100000个StringBuilder对象,所以费时
2.用StringBuilder
既然s+=“”;的方法底层是创建StringBuilder对象,那我们不妨直接创建StringBuilder,然后调用append方法进行拼接,这样便可以节省掉创建对象的时间
public void testStringBuilder(){
StringBuilder builder=new StringBuilder(" ");
Long start=System.currentTimeMillis();
for(int i=0;i<100000;i++){
builder.append("z"+i);
}
Long end=System.currentTimeMillis();
System.out.println("StringBuilder拼接字符串用时为:"+(end-start));
}
3.用StringBuffer
既然已经用StringBuilder优化了字符串拼接,为什么还要用StringBuffer呢??
我们通过查看StringBuffer的append方法可以发现,StringBuffer中的appen方法有synchronized修饰,则可以保证线程安全
不只是append方法,replace,subString等方法也有synchronized修饰,可见StringBuffer类更安全
StringBuilder与StringBuffer类在拼接字符串时代码的使用相似
public void testStringBuffer(){
StringBuffer buffer=new StringBuffer();
Long start=System.currentTimeMillis();
for(int i=0;i<100000;i++){
buffer.append("z"+i);
}
Long end=System.currentTimeMillis();
System.out.println("StringBuffer拼接字符串用时为:"+(end-start));
}
4.耗时对比
可见后两钟方式对耗时的提升是巨大的