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.