文章目录
- 1. 基本介绍
- 2. StringBuilder常用方法
- 3. String、StringBuffer 和 StringBuilder 的比较
- 4. String、StringBuffer 和 StringBuilder 的效率测试
- 5. String、StringBuffer 和 StringBuilder 的选择
1. 基本介绍
- 一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同
步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的一个简易
替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类因为在大多数实现中,它比StringBuffer要快。 - 在StringBuilder上的主要操作是
append
和insert
方法,可重载这些方法,以接受任意类型的数据。
1. StringBuilder 继承 AbstractStringBuilder 类
2. 实现了 Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
3. StringBuilder 是final类, 不能被继承
4. StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder的 char[] value; 因此,字符序列是堆中
5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized 关键字,因此在单线程的情况下使用 StringBuilder
public class StringBuilder01 {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
}
}
2. StringBuilder常用方法
-
StringBuilder和StringBuffer均代表可变的字符序列,方法是一样的,所
以使用和StringBuffer一样 -
使用方法可以参考我之前写的文章:StringBuffer类基本使用
-
看源码
3. String、StringBuffer 和 StringBuilder 的比较
- StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法
也一样 - String:不可变字符序列,效率低,但是复用率高。
- StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码
- StringBuilder:可变字符序列、效率最高、线程不安全
- String使用注意说明:
strings="a";//创建了一个字符串
s+="b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符
串s+"b"(也就是"ab”)。如果多次执行这些改变串内容的操作,会导致大量副
本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大
影响程序的性能=>结论:如果我们对String做大量修改,不要使用String
4. String、StringBuffer 和 StringBuilder 的效率测试
- 结论:String Vs StringBuffer Vs StringBuilder 效率 :
StringBuilder > StringBuffer > String
- 测试:
public class StringVsStringBufferVsStringBuilder {
public static void main(String[] args) {
int iterations = 80000; // 循环次数
int runs = 10; // 测试运行次数
double stringBufferTimeSum = 0;
double stringBuilderTimeSum = 0;
double stringTimeSum = 0;
// 预热 JVM
for (int i = 0; i < runs; i++) {
testStringBuffer(iterations);
testStringBuilder(iterations);
testString(iterations);
}
// 正式测试
for (int i = 0; i < runs; i++) {
stringBufferTimeSum += testStringBuffer(iterations);
stringBuilderTimeSum += testStringBuilder(iterations);
stringTimeSum += testString(iterations);
}
// 输出平均时间,单位为毫秒
System.out.println("StringBuffer 平均执行时间:" + (stringBufferTimeSum / runs / 1_000_000) + "ms");
System.out.println("StringBuilder 平均执行时间:" + (stringBuilderTimeSum / runs / 1_000_000) + "ms");
System.out.println("String 平均执行时间:" + (stringTimeSum / runs / 1_000_000) + "ms");
}
private static long testStringBuffer(int iterations) {
long startTime = System.nanoTime();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < iterations; i++) {
buffer.append(i);
}
long endTime = System.nanoTime();
return endTime - startTime;
}
private static long testStringBuilder(int iterations) {
long startTime = System.nanoTime();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < iterations; i++) {
builder.append(i);
}
long endTime = System.nanoTime();
return endTime - startTime;
}
private static long testString(int iterations) {
long startTime = System.nanoTime();
String text = "";
for (int i = 0; i < iterations; i++) {
text = text + i;
}
long endTime = System.nanoTime();
return endTime - startTime;
}
}
- 运行结果:
StringBuffer 平均执行时间:1.15511ms
StringBuilder 平均执行时间:0.95175ms
String 平均执行时间:2875.66084ms
5. String、StringBuffer 和 StringBuilder 的选择
使用的原则,结论:
- 如果字符串存在大量的修改操作,一般使用
StringBuffer
或StringBuilder
- 如果字符串存在大量的修改操作,并在单线程的情况,使用
StringBuilder
- 如果字符串存在大量的修改操作,并在多线程的情况,使用
StringBuffer
- 如果我们字符串很少修改,被多个对象引用,使用
String
,比如配置信息等
StringBuilder
的方法使用和StringBuffer
一样。