StringBuffer和StringBuilder相似,代表可变的字符序列。两个类都是抽象类AbstractStringBuilder的子类,因此方法几乎一模一样。区别在于StringBuffer线程安全,做线程同步检查,代价是效率的降低。
1.赋值
StringBuilder sb = new StringBuilder("XiAn");
2.常用方法
2.1 append()⭐
StringBuilder sb = new StringBuilder("XiAn");
sb.append("No.1");
System.out.println(sb);//XiAnNo.1
字符串追加方法,从结果上看像是两个字符串的拼接,在对原字符串调用方法后,字符串本身是发生了改变的,很明显的区别于String类复制再做操作的方法,效率更高。
2.2 insert()
StringBuilder sb = new StringBuilder("XiAn");
sb.insert(2,"-");
System.out.println(sb);//Xi-An
在指定位置插入字符串,很明显的能感觉到底层也是一个char类型数组。
2.3 charAt()
和String一模一样,但StringBuilder是继承自父抽象类的方法
2.4 setCharAt()
StringBuilder sb = new StringBuilder("XiAn");
sb.setCharAt( 1 , 'A' );
System.out.println(sb);//XAAn
替换指定位置的字符,只能替换字符,不能替换字符串。
2.5 replace()
StringBuilder sb = new StringBuilder("XiAn");
sb.replace(0,1,"SSS");
System.out.println(sb);//SSSiAn
sb.replace(0,2,"XXX");
System.out.println(sb);//XXXSiAn
替换指定位置的字符串,覆盖区间是[0,1),后面的删除方法同样。
2.6 deleteCharAt()
StringBuilder sb = new StringBuilder("XiAn");
sb.deleteCharAt(1);
System.out.println(sb);//XAn
删除指定位置的字符。
2.7 delete()
StringBuilder sb = new StringBuilder("XiAn");
sb.delete(1,2);
System.out.println(sb);//Xn
删除只能位置的字符串。删除区间[a,b)
2.8 reverse()⭐
StringBuilder sb = new StringBuilder("XiAn");
System.out.println( sb.reverse());
反转字符串。
3. 转换
String sb = "XiAn";
StringBuilder sb1 = new StringBuilder(sb);// String转换为StringBuilder
String s = sb1.toString(); //StringBuilder转换为String
4. 小结
StringBuilder相较于String有快速拼接代码的能力,但是可操作方法少于String,一般使用String当需要拼接字符串时,临时将String类转换为StringBuilder类待拼接完成后,再转回去。
5. 一些疑问
5.1 字符串长度问题
在调用前面的方法时,很明显的感受到StringBuilder实际上也是一个char类型的数组,与String不同的是StringBuilder在添加字符串时并不是像String一样重新申请一块内存和数组对新数组进行操作,而是直接在char[]上进行操作,他是怎么实现数组不溢出的呢?
StringBuilder sb1 = new StringBuilder();//通过ctrl+左键进入构造函数
/************************************************************************
* public StringBuilder() {
* super(16);
* }
*StringBuilder类中默认申请长度为16的char[]*
***********************************************************************/
//当我们创建一个新对象
StringBuilder test = new StringBuilder("AAA");
System.out.println(test.length());// 3
//很明显与数组实际长度不符。下面调用类中输出实际数组长度的方法
System.out.println(test.capacity());// 19
//通过源代码可以得出 初次申请 数组长度 = 字符串长度 + 16
//
//调用append方法将字符串延长至20后,输出数组实际长度
for (int i = 0 ; i < 17 ; i++){
test.append("a");
}
System.out.println("扩容第一次:"+
test.capacity()); //扩容第一次: 40
//再次延长至41
for (int i = 0 ; i < 21; i++){
test.append("a");
}
System.out.println("扩容第二次:"+
test.capacity()); // 扩容第二次:82
//发现扩容按照 (原长度 + 1)*2 的公式增加
以字符串"AAA"为例,String类调用concat()方法增加40次字符串长度,需要申请40次新对象,而StringBuilder只需要扩容1次。