String、StringBuilder、StringBuffer
像会永生那样去学习,像明天就要死亡那样去生活。
——圣雄甘地
String
Java提供了String类来创建和操作字符串。在二进制中可以看到,String类内部的实现也是一个字节数组,这个数组是final类型的,因此String是不可变的对象,每次在对字符串类进行改变的时候都会生成一个新的字符串对象,然后将指针指向新的字符串对象。
StringBuilder
和String类不同的是,StringBuilder类的对象能够被多次修改,并且不产生新的对象。这个特性的意义在于,如果我们进行大量的字符串操作,使用字符串类就会产生很大的性能消耗,而StringBuilder就可以避免这个问题。
StringBuffer
StringBuffer和StringBuiler之间的最大不同在于StringBuilder的方法不是线程安全的。
由于StringBuilder相比较于StringBuffer有速度优势,所以多数情况下建议使StringBuilder类。而在应用程序中要求线程安全的情况下,则必须使用StringBuffer类。
| 对比项 | String | StringBuilder | StringBuffer |
|---|---|---|---|
| 可变性 | 不可变(Immutable) | 可变(Mutable) | 可变(Mutable) |
| 线程安全 | 线程安全(天然不可变) | 非线程安全(不同步) | 线程安全(同步方法) |
| 性能 | 低(频繁修改产生新对象) | 高(非同步,速度快) | 中等(同步带来额外开销) |
| 适用场景 | 字符串常量、少量拼接 | 单线程下大量字符串操作 | 多线程下大量字符串操作 |
| 存储方式 | 字符串常量池 | 堆内存 | 堆内存 |
| 继承关系 | 实现CharSequence | 继承AbstractStringBuilder | 继承AbstractStringBuilder |
| 方法同步 | - | 无同步 | 关键方法加synchronized |
| JDK版本 | 1.0 | 1.5 | 1.0 |
- 可变性:String每次修改都生成新对象,StringBuilder/Buffer直接修改内部char数组
- 线程安全:StringBuffer通过synchronized保证线程安全,Builder不保证
- 性能排序:StringBuilder > StringBuffer > String(在频繁修改场景)
- 版本差异:StringBuilder是JDK1.5优化的非线程安全版本
String,StringBuilder和StringBuffer的比较各种字符串操作的效率测试
测试代码
@Test
public void test() {
int count = 100000;
long startTime = System.currentTimeMillis();
String str = "";
for (int i = 0; i < count; i++) {
str += i;
}
System.out.println("执行" + count + "次 String 耗时:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < count; i++) {
stringBuilder.append(i);
}
System.out.println("执行" + count + "次 StringBuilder 耗时:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < count; i++) {
stringBuffer.append(i);
}
System.out.println("执行" + count + "次 StringBuffer 耗时:" + (System.currentTimeMillis() - startTime));
测试结果
执行100000次 String 耗时:20005
执行100000次 StringBuilder 耗时:1
执行100000次 StringBuffer 耗时:3
可以看到String类的性能远低于StringBuiler和StringBuffer,而StringBuiler在本次测试中比Stringbuffer提高了50%的性能
总结
如果不涉及串联操作,那么String类是首选,如果涉及的串行操作没有线程安全问题,那么使用StringBuilder,如果涉及的串行操作存在线程安全问题,那么使用StringBuffer。

浙公网安备 33010602011771号