String,StringBuilder,StringBuffer比较
1、String是字符串常量,定义后String就不可变,对String的操作时,本质是生成了新的String对象。
StringBuilder和StringBuffer是字符串变量,对其操作直接修改变量本身。
所以字符串操作StringBuilder和StringBuffer要比String快。
例如:
String s = "";
long start = System.currentTimeMillis();
for(int i = 0; i < 10000; i++) {
s = s + i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);//1210
StringBuilder sb = new StringBuilder();
long start1 = System.currentTimeMillis();
for(int i = 0; i < 10000; i++) {
sb.append(i);
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);//0
StringBuffer sb1 = new StringBuffer();
long start2 = System.currentTimeMillis();
for(int i = 0; i < 20000; i++) {
sb1.append(i);
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);//2
可见,如需频繁操作字符串,尽量避免使用String,可使用StringBuilder和StringBuffer。
2、StringBuilder和StringBuffer区别。
StringBuilder是线程不安全的,StringBuffer是线程安全的。
当多个线程同时访问StringBuilder对象,可能出现意料意外的情况。
当多个线程同时访问StringBuffer对象,StringBuffer的很多方法synchronized关键字,会加锁,保证同时只能有一个对象访问它。
例如:
public static void operate(StringBuffer sb, StringBuilder sb1) {
new Thread(){
public void run() {
for (int i = 0; i < 10000; i++) {
sb.append(i);
sb1.append(i);
}
System.out.println(sb.length());
System.out.println(sb1.length());
}
}.start();
}
public static void main(String [] args) {
StringBuffer sb = new StringBuffer();
StringBuilder sb1 = new StringBuilder();
operate(sb, sb1);
operate(sb, sb1);
}
有两个线程操作StringBuilder和StringBuffer对象,该程序执行多次,StringBuffer对象最终长度应该始终相同,StringBuilder对象的长度则是未知的。
执行5次,结果如下:
StringBuffer: 77780 77780 77780 77780 77780
StringBuilder:77162 77780 77316 44797 76407
可以得出,StringBuilder对象的确是线程不安全的