1、简介
StringBuffer,由名字可以看出,是一个String的缓冲区,也就是说一个类似于String的字符串缓冲区,和String不同的是,它可以被修改,而且是线程安全的。StringBuffer在任意时刻都有一个特定的字符串序列,不过这个序列和它的长度可以通过一些函数调用进行修改。它的结构层次如下图:
StringBuffer是线程安全的,因此如果有几个线程同时操作StringBuffer,对它来说也只是一个操作序列,所有操作串行发生。
每一个StringBuffer都有一个容量,如果内容的大小不超过容量,StringBuffer就不会分配更大容量的缓冲区;如果需要更大的容量,StringBuffer会自动增加容量。和StringBuffer类似的有StringBuilder,两者之间的操作相同,不过StringBuilder不是线程安全的。虽然如此,由于StringBuilder没有同步,所以它的速度更快一些。
2、StringBuffer对象的初始化
StringBuffer对象的初始化不像String类的初始化一样,Java提供的有特殊的语法,而通常情况下一般使用构造方法进行初始化。
例如:
StringBuffer s = new StringBuffer();
这样初始化出的StringBuffer对象是一个空的对象。
如果需要创建带有内容的StringBuffer对象,则可以使用:
StringBuffer s = new StringBuffer(“abc”);
这样初始化出的StringBuffer对象的内容就是字符串”abc”。
需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:
StringBuffer s = “abc”; //赋值类型不匹配
StringBuffer s = (StringBuffer)”abc”; //不存在继承关系,无法进行强转
StringBuffer对象和String对象之间的互转的代码如下:
String s = “abc”;
StringBuffer sb1 = new StringBuffer(“123”);
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer
String s1 = sb1.toString(); //StringBuffer转换为String
3、常用方法
StringBuffer类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
(1)构造函数
StringBuffer有四个构造函数:
- StringBuffer() value内容为空,并设置容量为16个字节;
- StringBuffer(CharSequece seq) 使用seq初始化,容量在此基础上加16;
- StringBuffer(int capacity) 设置特定容量;
- StringBuffer(String str) 使用str初始化,容量str大小的基础上加16;
(2)append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”。
(3)deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“Test”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
(4)insert方法
public StringBuffer insert(int offset, boolean b)
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
(5)reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
(6)setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
(7)toString方法
public void toString()
使用StringBuffer的toString()方法,可以将StringBuffer转换成String
StringBuffer sb = new StringBuffer(“abcd”) ;
sb.append(“efg”) ;
String str = sb.toString() ;
(8)其它会改变内容的方法
上面的那些方法会增加StringBuffer的内容,还有一些方法可以改变StringBuffer的内容:
- StringBuffer delete(int start,int end) 删除从start到end(不包含)之间的内容;
- StringBuffer deleteCharAt(int index) 删除index位置的字符;
- StringBuffer replace(int start,int end,String str)用str中的字符替换value中从start到end位置的子序列;
- StringBuffer reverse() 反转;
- void setCharAt(int index,char ch) 使用ch替换位置index处的字符;
- void setLength(int newLength) 可能会改变内容(添加’\0’);
(9)其它常用方法
下面这些方法不会改变内容:
- int capacity() 返回value的大小即容量;
- int length() 返回内容的大小,即count;
- char charAt(int index) 返回位置index处的字符;
- void ensureCapacity(int minimumCapacity) 确保容量至少是minimumCapacity;
- void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)返回srcBegin到srcEnd的字符到dst;
- int indexOf(String str) 返回str第一次出现的位置;
- int indexOf(String str,int fromIndex) 返回从fromIndex开始str第一次出现的位置;
- int lastIndexOf(String str) 返回str最后出现的位置;
- int lastIndexOf(String str,int fromIndex) 返回从fromIndex开始最后一次出现str的位置;
- CharSequence subSequence(int start,int end) 返回字符子序列;
- String substring(int start) 返回子串;
- String substring(int start,int end) 返回子串;
- void trimToSize() 缩小value的容量到真实内容大小;
4、与String和StringBuilder的区别
三者都是处理字符串常用的类,不同在于:
速度上:String<StringBuffer<StringBuilder
安全上:StringBuffer线程安全,StringBuilder线程不安全;
原因在于,String的每次改变都会涉及到字符数组的复制,而StringBuffer和StringBuilder直接在字符数组上改变;同时,StringBuffer是线程安全的,而StringBuilder线程不安全,没有StringBuffer的同步,所以StringBuilder快于StringBuffer。
总结:
如果对字符串的改变少,使用String;
如果对字符串修改的较多,需要线程安全就用StringBuffer,不需要就使用StringBuilder。
···
public class stringtestone {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer(5);
sb.append("howareyou");
System.out.println("sb的内容为:"+sb);
System.out.println("sb.length():"+sb.length());
System.out.println("sb.capacity():"+sb.capacity());
sb.deleteCharAt(2);
System.out.println("sb.deleteCharAt后的内容为:"+sb);
sb.insert(5, "Test");
System.out.println("sb.insert后的内容为:"+sb);
sb.reverse();
System.out.println("sb.reverse后的内容为:"+sb);
String str=sb.toString();
System.out.println("String中str的内容为:"+str);
}
}
程序运行结果为:
sb的内容为:howareyou
sb.length():9
sb.capacity():12
sb.deleteCharAt后的内容为:hoareyou
sb.insert后的内容为:hoareTestyou
sb.reverse后的内容为:uoytseTeraoh
String中str的内容为:uoytseTeraoh
···