String是immutable类,则每次对String操作都会产生新的String对象,这样效率十分底下,而且浪费内存。
StringBuffer是可变的类和线程安全的字符串操作类,任何对它指向的字符串操作都不会产生新的对象。
StringBuilder类与StringBuffer类的功能基本相同。
下面我们来具体阐释一下三种类的用法:
1、String类:
String类是不可变的类,导致每次对String的操作都会产生新的String对象,这样的操作效率低下,而且浪费内存。
例如:String a=“hello”,假设a字符串指向的地址为0x0002,a=“java”,重新赋值后指向的地址指向0x0003,但是原来的地址0x0002中保存的“hello”仍然存在,但已经不是字符串a所指向的地址了,因为这时候字符串a指向了“java”字符串的地址。因此String的操作都是改变赋值地址而不是改变值操作。
2、StringBuffer类:
StringBuffer是可变的类和线程安全的字符串操作类,任何对它指向的字符串操作都不是产生新的对象。每一个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。默认情况下,StringBuffer会分配16字节的字符缓冲区。
StringBuffer buf=new StringBuffer();这是默认情况下,分配16字节的字符缓冲区
StringBuffer buf=new StringBuffer(512);分配长512字节的字符缓冲区
StringBuffer buf=new StringBuffer(“hello,this is Java”);在缓冲区中存放了字符串,并在后面预留了16个字节的缓冲区
3、StringBuilder类:
StringBuilder类和StringBuffer类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比较而言,StringBuilder类会略微快一点,对于经常要改变值的字符串,应该使用StringBuffer类或者StringBuilder类。
StringBuffer类:线程安全
StringBuilder类:线程不安全
速度比较:StringBuilder类最快,StringBuffer类次之,String类最慢,当然这种比较是相对的,不是绝对的。
使用情况总结:
1、当操作的数据量较少时:使用String类
2、单线程操作字符串缓冲区下操作大量的数据时:使用StringBuilder类
3、多线程操作字符串缓冲区下操作大量的数据时:使用StringBuffer类
下面放上一些比较的源码:
package programmer;
public class TestString3 {
final static int times = 50000; // 循环次数
public void test(String s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
s += "add";
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
}
public void test(StringBuffer s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getCanonicalName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
}
public void test(StringBuilder s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
} /* 对 String 直接进行字符串拼接的测试 */
public void test2() {
String s2 = "abcd";
long begin = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
String s = s2 + s2 + s2;
}
long over = System.currentTimeMillis();
System.out.println("操作字符串对象引用相加类型使用的时间为:" + (over - begin) + "毫秒");
}
public void test3() {
long begin = System.currentTimeMillis();
for (int i = 0; i < times; i++) {
String s = "abcd" + "abcd" + "abcd";
}
long over = System.currentTimeMillis();
System.out.println("操作字符串相加使用的时间为:" + (over - begin) + "毫秒");
}
public static void main(String[] args) {
String s = "abcd";
StringBuffer sbf = new StringBuffer("abcd");
StringBuilder sbd = new StringBuilder("abcd");
TestString3 tc = new TestString3();
tc.test(s);
tc.test(sbf);
tc.test(sbd);
tc.test2();
tc.test3();
}
}
运行结果如下:
运行结果可以看出三者之间的区别。