StringBuffer
Buffer的意思是缓冲,缓冲区。
它与String的区别是
String一旦被创建,不能被改变。
而StringBuffer可以对字符串进行修改。
StringBuffer是一个容器。特点:
1长度可变。(数组长度不可变)
2可以操作多个数据类型。(数组只能操作一种类型)
3最终会通过toString方法变成字符串。
什么时候用?
当数据类型或个数不确定,而且最重要变成字符串的时候,
容器是可以放数据的。那这个容器应该具备什么功能呢?
这里先说明一下,字符串缓冲区,终究是跟字符串打交道,所以,我们向里面添加许多不同类型的数据,最后都要转换成字符串进行处理。
而容器的特点就是对数据的改变:CURD。
1.存储(增)C create
Java.lang包下有StringBuffer类,也是final修饰,不能去继承。
它除了一堆的构造函数之外,还有一堆append()方法。这就是添加方法,而添加的数据包括基本数据类型。但是有两种基本数据类型没有:byte和short。为什么没有呢?因为这个添加的方法可以添加int类型参数,而byte和short是可以类型提升的。
StringBuffer append():将指定的数据作为参数添加到已有数据的结尾处。
那么在这里我们就写个小demo
1 Class StringBufferDemo 2 3 { 4 5 Public static void main(String[] args) 6 7 { 8 9 //既然是对其进行操作,就先创建一个缓冲区对象 10 11 //当然创建的时候,根据api构造方法,我们是可以向里面传入字符串。 12 13 //也可以是空 14 15 StringBuffer sb = new StringBuffer(); 16 17 //那么接下来就是添加数据 18 19 //返回类型还是StringBuffer 20 21 StringBuffer s1 = sb.append(34); 22 23 //这里把缓冲区变成字符串并打印(sb是对象,继承自父类Object,用父类的//toString()方法) 24 25 Sop(sb.toString()); 26 27 Sop(sb1.toString()); 28 29 } 30 31 Public static void sop(String str) 32 { 33 34 System.out.println(str); 35 36 } 37 38 }
输出结果为:
34
34
可能有的朋友会问sb里面不应该什么也没有吗,sb1不应该添加完东西返回一个新的吗?
这里在打印个东西,大家就明白了
System.out.println(sb==sb1);
结果为:true.
这也就验证了:sb和sb1是同一对象。
缓冲区这里有个理论叫面盆理论。
在一个盆里放点面,加点水,和一和,揉一揉。这个盆就是StringBuffer,添了面(加了东西),还是这个盆,加了水(又加了其他东西),还是这个盆,还是StringBuffer。揉成面团了,还是这个盆,面团上加两个枣,还是这个盆,把枣去掉,还是这个盆,把面团扔了,还是这个盆。
所以,上面那段代码是麻烦的写法,简单可以如下:
Sp.append(“abd”).append(true).append(34);
这样的写法叫做方法调用链。
这样,打印出来的结果也是一段字符串:
Abdtrue34
当然,上述append()方法只能在原有基础上的结尾添加,不够灵活。
还有个insert()方法他就可以灵活的添加(添加到头、尾、中间),也有很多重载方法
StringBuffer insert(index, 数据):可以将数据插入到指定index位置。注意如果没有该脚标位置,报脚标位越界异常。
例如,我想在abdtrue34这个字符串中的a后添加内容,代码就是这样的:
Sb.insert(1,”qq”);
输出打印结果:
aqqbdtrue34
2.删除(删)D delete
StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end.
StringBuffer deleteCharAt(index):删除缓冲区中指定位置的字符。
这里就不做实例了。但需注意:
做清空缓冲区的操作,应该是sb.delete(0,sb.length());而不是重新new StringBuffer();(这样是在内存中重新开辟内存空间创建缓冲区,耗费内存)
3.获取(查) R read
Char charAt(int index):通过脚标获取字符
Int indexOf(String str):根据字符串获取相应位置。
IntlastIndexOf(String str): 根据字符串获取最后一次出现的相应位置
Int length():获取字符串的长度
String substring(int start):
String substring(int start,int end):
4.修改(改)U update(替换)
把原来字符串中数据改变,不是添加。
StringBuffer replace(int start,int end,String str):头,尾,所替换的内容,注意被替换的和所替换的长度可以不相同。
Void setCharAt(int index,char ch):替换单个字符,替换完后就完事,不反悔任何数据。
5.反转
StringBuffer Reverse();
以上这些方法要熟记。
6.将缓冲区中的指定数据存储到指定字符数组中。
Void getChars(int srcBegin,intsrcEnd,char[] dst, int dstBegin)
遵循包含头不包含尾,如果所取的字符不够数组长度,多余脚标的用空字符占位。如果开始的脚标位到数组末尾的长度小于所取得的字符串的长度,出现脚标越界异常。
StringBuilder
它是一个可变的字符序列。提供了一个与StringBuffer兼容的API,(即功能一样)但不能够同步。该类被设计用作StringBuffer的一个简易替换。
而StringBuffer是一个线程安全的可变字符序列。
JDK1.5才出现StringBuilder
StringBuilder与StringBuffer的区别在于:
StringBuffer是线程同步的;
StringBuilder是线程不同步的。
先说一下线程的问题,一个容器,我们在向里面存储数据时,另外一个线程在做其他操作,比如修改或删除,那么数据在取得时候就会错乱。(并发执行产生错乱。)
那么当一个线程对数据进行操作时,其他线程则不能对数据进行操作,这是同步。StringBuffer就是这样的。是安全的,在添加的时候,是不能有其他操作的。多线程情况也不会。StringBuilder是不安全的。
那为什么选择SringBuilder呢?
如果是单线程程序,StringBuffer效率低,因为它要判断锁。而SringBuilder不需要锁,更快捷。
将StringBuilder的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用StringBuffer.
Java的升级无外乎三个方面:1,提高效率
2,简化书写
3,提高安全性。
而StringBuilder在1.5中出现正是为了提高效率。
以后开发,建议使用StringBuilder.