String 和 StringBuffer 和 StringBuilder
他们都是用来处理字符串的,String字符串常量,StringBuffer与StringBuilder是字符串变量
String:
String 是不可变的对象(final修饰),保存的是字符串常量(在常量池中),里面的字符序列不能被更改,每次对字符串的改变,都是在常量池中创建了一个新的字符串(对象/空间/地址),这样效率低下,大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String
StringBuffer与StringBuilder:
StringBuffer是可变字符串、效率低、线程安全
StringBuilder是可变字符序列、效率高、线程不安全;
他们在初始化时后面括号中放的是字符串长度,如果为空白则默认长度为16
他们有相同的继承结构:
三种方式字符串拼接耗时测试:
public static void main(String[] args) {
long startTime = 0L;
long endTime = 0L;
StringBuffer buffer = new StringBuffer("");
startTime = System.currentTimeMillis();
// StringBuffer 拼接 20000次
for (int i = 0; i < 100000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime)+"ms");
//===============================================================================================
StringBuilder builder = new StringBuilder("");
startTime = System.currentTimeMillis();
// StringBuilder 拼接 20000次
for (int i = 0; i < 100000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime)+"ms");
//===============================================================================================
String text = "";
startTime = System.currentTimeMillis();
// String 拼接 20000
for (int i = 0; i < 100000; i++) {
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime)+"ms");
}
结果:
各十万次的简单拼接测试,StringBuffer与StringBuilder速度极快且不相上下,而String拼接则慢了非常多
StringBuffer与StringBuilder的线程安全测试:
public class StringBufferTest {
StringBuilder sb=new StringBuilder();
StringBuffer sb1=new StringBuffer();
public StringBufferTest() {
ThreadGroup group = new ThreadGroup("testGroup");
MyThread at=new MyThread();
for(int i=0;i<1000;i++){
Thread th=new Thread(group,at,String.valueOf(i));
th.start();
}
while (group.activeCount() > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(sb.length());
System.out.println(sb1.length());
}
public static void main(String[] args) {
new StringBufferTest();
}
class MyThread implements Runnable {
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
sb.append("1");
sb1.append("1");
}
}
}
结果:
模拟1000个线程,使用用StringBuffer和StringBuider添加字符串,测试结果是StringBuffer添加的字符串长度为1000,而StringBuider长度为980,因为StringBuider的append方法没有synchronized关键字的,因此在执行过程中原本已经添加的字符串可能被后一个线程所替换
StringBuffer 的append方法被synchronized的所修饰:详情可见 >>>>> Synchronized关键字的简单认识
总结:
1.String字符串常量(不可变),StringBuffer与StringBuilder是字符串变量
2.如果要操作少量的数据,用String ,单线程操作大量数据,用StringBuilder ,多线程操作大量数据,用StringBuffer。
3.不要使用String类的"+"来进行频繁的拼接,性能极差,应该使用StringBuffer或StringBuilder类
下一篇 >>>>> Synchronized关键字的简单认识
That’s it;
物物而不物于物,念念而不念于念。