废话不多说,上代码!!!
public class test {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder("abcd");
StringBuffer stringBuffer = new StringBuffer("ABCD");
System.out.println(stringBuilder.append("abcd")); //字符串拼接
System.out.println(stringBuffer.append("ABCD"));
System.out.println(stringBuilder.append(stringBuilder));
System.out.println(stringBuilder.append(stringBuffer));
System.out.println(stringBuffer.delete(4,8)); //删除第4到8(左开右闭)的字符
System.out.println(stringBuilder.delete(4,24)); //删除第4到24(左开右闭)的字符
System.out.println(stringBuffer.deleteCharAt(0)); //删除第一个位置上的字符
System.out.println(stringBuffer.replace(2,3,"a")); //替换
System.out.println(stringBuffer.insert(0,"A")); //在指定位置开始插入目标字符
System.out.println(stringBuffer.replace(3,4,"D")); //将第三到第四(左开右闭)替换成目标字符串
System.out.println(stringBuffer.indexOf("A")); //指定字符串出现的最开始的位置
System.out.println(stringBuffer.lastIndexOf("A")); //指定字符串出现的最后的位置
System.out.println(stringBuffer.reverse()); //翻转
}
}
运行结果:
abcdabcd
ABCDABCD
abcdabcdabcdabcd
abcdabcdabcdabcdABCDABCD
ABCD
abcd
BCD
BCa
ABCa
ABCD
0
0
DCBA
容易看到第三个和第四个的结果非常长。那么是为什么呢?
先上原理:
StringBuffer、StringBuilder和String类似,底层也是用一个数组来存储字符串的值,并且数组的默认长度为16,即一个空的StringBuffer对象数组长度为16。实例化一个StringBuffer对象即创建了一个大小为16个字符的字符串缓冲区。但是当我们调用有参构造函数创建一个StringBuffer对象时,数组长度就不再是16了,而是根据当前对象的值来决定数组的长度,数组的长度为“当前对象的值的长+16”。所以一个 StringBuffer 创建完成之后,有16个字符的空间可以对其值进行修改。如果修改的值范围超出了16个字符,会先检查StringBuffer对象的原char数组的容量能不能装下新的字符串,如果装不下则会对 char 数组进行扩容。
大白话:StringBuffer、StringBuilder底层虽然都是char数组,但是在进行创建的时候预留了可扩容的存储空间,所以在预留扩容空间内的扩容,扩容之后还在原地。超过扩容空间之后就新建一个新的地址,复制原有的部分,然后再把新加部分加在后面,最后让原StringBuffer/StringBuilder指向新的地址。部分内容参考: