为什么会有String?
String是字符串的意思。但是是否注意到String首字母是大写呢,一般什么才会首字母大写?当然是类了。
String类表示内容不可改变的字符串。
什么叫不可改变呢?
String str = "abc";
str = "bcd";
System.out.println(str); //输出为bcd
类似于
Person p = new Person();
System.out.println(p.toString()); //输出为com.junc.test.Person@15db9742
p = new Person();
System.out.println(p); //输出为com.junc.test.Person@6d06d69c
两者的P是不同的,所以同理,两者的str也是不同的,说明abc并没有被改变。这就是为什么说String类表示内容不可以改变的字符串。
那么不可变会带来什么样的不好的影响呢?
String s = "hello";
s = s + "world!";
上面这两行代码执行后,原始的String对象中的内容变了没有呢?
答案是没有,因为我们说了String类是不可变类,当执行s = s + "world!"
时,只是之前的s不指向原来那个对象了,那个对象还在内存中。那么使用String来代表字符串的话会引起很大的内存开销,就会导致内存消耗过多而使程序运行的非常慢,也就是手机或电脑常出现的卡机现象。
怎么办呢?为什么会有StringBuffer?
我们想到了一种办法,就是再设计一个可变的,这样就不用每次再创建新的对象而制造垃圾了。命名为StringBuffer。Buffer是缓冲区的意思,也就是说将String放入一个缓冲区,在这个区域内不断改变字符串就可以了。
package com.junc.test;
public class TestString3 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
StringBuffer sb1 = sb.append("a");
StringBuffer sb2 = sb.append("b");
System.out.println(sb1); //输入出ab
}
}
当打印sb1而不是sb2的时候,输出结果是ab。这就代表着StringBuffer是一个改变的,共用了一个缓冲区,在这个缓冲区内进行操作,如此效率才高。
当然,一个初步的新生事物,我们是要保证安全的。
故StringBuffer是线程安全的,并且是可变的字符序列。
为什么会有StringBuilder?
在我们的生活中,安全代表着什么?为了安全,我们加了一道门。为了安全,我们加了一个锁,但要是你有急事,想快点回家拿个东西,是不是还要先拿钥匙,找到钥匙,打开门才行。这样效率是不是显得很低。
那么怎么提高效率呢?不要安全了,不要门,可以直接进去拿东西。
为了应对这样情况,我们又创建了一个新的类:StringBuilder.
它是线程不安全的,但运行效率会比StringBuffer更高。
所以,在不存在不安全情况的时候,我们还是要选择StringBuilder。
但晚上睡觉,存在不安全情况的时候,我们还是要选择StringBuffer。
耗时比较:
package com.junc.test1;
public class Test1 {
public static void main(String[] args) {
//StringBuffer用时
long start1 = System.currentTimeMillis();
StringBuffer sb1 = new StringBuffer();
for(int i = 0; i < 1000000; i++) {
sb1.append(i).append(" ");
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1); //输出78
//StringBuilder用时
long start2 = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder();
for(int i = 0; i < 1000000; i++) {
sb2.append(i).append(" ");
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);//输出31
}
}
总结:
String是不可变的字符序列。
StringBuffer是线程安全的,可变的字符序列,效率比String高。
StringBuilder是线程不安全的,可变的字符序列,效率比StringBuffer更高。