StringBuffer与StringBuilder
在生产中不要使用String进行太多的拼接。
例如
String a = "hello";
String b = "world";
String str = a + b;
String字符串的拼接的过程中会创建很多个临时字符串。
String是一种常量,字符串中的字符是通过一个final修饰的char[]数组来保存的。
String字符串的值一旦确定则不可修改。
我们进行的所有字符串的拼接、替换、拆分、插入、截取等等方法,
实际上都是在内存中生成了新的字符串对象,并没有在原有字符串的值上做修改。
对于字符串的拼接,可以使用StringBuffer和StringBuilder进行优化。
- StringBuffer和StringBuilder是两种可变长字符串,
- 是具有缓冲功能和可修改的特性。
字符串的内容可能会经过很多次的调整,
例如对字符串中的字符进行增删改查。
传统的String会把过程中的每一步临时修改都生成一个新的字符串,
但是这些字符串都没有实用价值,而且还会长时间占用内存。
缓冲的优化思路是:
- 在字符串修改的过程中,不会生成新的String对象。
- 而是把要生成的字符串内容临时保存在一个缓冲数组中。
- 等修改完毕确认要生成字符串的时候直接生成一次最终的结果即可。
StringBuffer和StringBuilder的异同点:
- 它们都是可拼接的字符串,都继承同一父类,具有相同的功能。
- StringBuffer线程安全,但效率低
StringBuilder线程不安全,但效率高
源码分析:
append的实现
- 基本使用
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("你好");
sb.append("世界");
System.out.println(sb.toString());
}
- StringBuffer的append源码:在每一次调用append方法时,都会将toStringCache设置为null
@Override
public synchronized StringBuffer append(String str) {
//拼接要修改字符数组,所以将缓冲置为空
toStringCache = null;
//调用父类的append方法
super.append(str);
return this;
}
- 1 toStringCache:根据java的注释可以知道,他是最后一个调用toString方法生成的字符串内容,只要字符串发生了改变,这个缓冲就会被清空。
相当于一个缓冲区,避免多次拷贝真正的char数组
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
- 2 toString方法:如果此时缓冲为空的话,就将父类中真正的value字符数组拷贝过来,之后直接用自己的字符数组创建String对象
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
- 3 父类AbstractStringBuilder的append方法
public AbstractStringBuilder append(String str) {
//如果为null的话,就返回一个appendNull的结果,点进去看一下就知道,这里就不再看了
if (str == null)
return appendNull();
//获得要拼接的字符串长度
int len = str.length();
//确保字符数组长度够用,不够就扩容,这里不做过多赘述,如果容量不够则value = Arrays.copyOf(value,newCapacity(minimumCapacity));来进行扩容
ensureCapacityInternal(count + len);
//将str从0开始到len的位置拷贝到value数组中,从count位置开始存放(aka 将str拼接到value后面)
str.getChars(0, len, value, count);
//然后增加value的长度
count += len;
//返回
return this;
}
本博客文章主要供博主学习交流用,所有描述、代码无法保证准确性,如有问题可以留言共同讨论。

浙公网安备 33010602011771号