标签:程序 和我 常量池 for循环 执行 用法 https mem i++
StringBuilder > StringBuffer > String
我们来做一个测试,我们分别使用String和StringBuilder创建变量,然后分别对它们进行加字符串操作,由于时间太短,我们把这个过程使用for循环重复100000遍以放大差距:
public static void main(String[] args)
{
Long start1 = System.currentTimeMillis();//获取开始时间
for (int i=0;i<100000;i++)//重复10万次进行String变量加操作
{
String str = "a";
str+="b";
}
Long end1 = System.currentTimeMillis();//获取结束时间
System.out.println("String花费时间:"+(end1-start1));//打印出花费的时间
Long start2 = System.currentTimeMillis();
for (int i=0;i<100000;i++)//重复10万次进行StringBuilder变量加操作
{
StringBuilder str2 = new StringBuilder("a");
str2.append("b");
}
Long end2 = System.currentTimeMillis();
System.out.println("StringBuilder花费时间:"+(end2-start2));
Long start3 = System.currentTimeMillis();
for (int i=0;i<100000;i++)//重复10万次进行StringBuffer变量加操作
{
StringBuffer str2 = new StringBuffer("a");
str2.append("b");
}
Long end3 = System.currentTimeMillis();
System.out.println("StringBuffer花费时间:"+(end2-start2));
}
实验结果:
可以看到,放大了差距之后,String和StringBuilder、StringBuffer两兄弟的差距还是蛮大的,那么是什么造成了这种差距呢?
在上面的程序中:
String str = "a";
str+="b";
这句话看似是对同一个String类型的str对象进行了加操作,但是实际上可不是同一个对象,事实上,我们先声明了一个String类型的对象,值是"a",把str这个句柄指向了这个对象,然后,当我们把这个对象进行+=操作的时候,实际上是又创建了一个String对象,这个对象的值是"a"+“b"也就是"ab”,然后改变句柄str让它指向了这个新的对象,原来的对象失去了引用,就被jvm垃圾回收了。而StringBuffer和StringBuilder可不是这样,这两兄弟是直接改变自己本身对象的值。
那么,当我们进行了10万次操作的时候,快慢差距自然就体现出来了。
这里有人会问了,如果我把这句代码:
String str = "a";
str+="b";
改为:
String str = "a"+"b";
呢?
让我们看一下执行效果:
哪怕是进行10万次操作,String所花费的时间也是极少的,这是为什么呢?
这是因为String和我们其它类型的变量不同,其它的非基本类型对象的值、数据都存储在java的堆中,而String类型的变量的值是存储jvm在方法区中的字符串常量池中的。当我们执行:String str = “a”+“b”;这句话的时候,String会自动把这个对象的值看成"ab",然后在方法区中如果找到了值同样为"ab"的,就会直接让str句柄指向它,也就是说,我们的这句代码现在相当于:
String str = "ab";
这可比之前的String用法一遍遍反复地去创建对象回收对象快多了,因此,即使重复10万次依然还是很快。
StringBuffer是线程安全的,而StringBuilder是线程不安全的,实验的具体方法见此链接:https://blog.csdn.net/litterfrog/article/details/76862435
String适用于少量的字符串操作的情况
StringBuilder适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer适用多线程下在字符缓冲区进行大量操作的情况
转自:https://blog.csdn.net/qq_37856300/article/details/84340288
String、StringBuffer、StringBuilder的区别
标签:程序 和我 常量池 for循环 执行 用法 https mem i++
原文地址:https://www.cnblogs.com/whjykgz/p/12345467.html