StringBuffer
StringBuffer
1:字符串缓冲区
2:mutable 可变的。
3:java.lang.AbstractStringBuilder
Stringbuffer
toString()方法:
//进行输出
StringBuffer s1 = new StringBuffer();
s1.toString();
append()方法
//用来初始化
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
charaAt()方法
//返回指定索引位置的字符,索引从0开始
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
System.out.println( buffer.charAt(4));
结果:
国
deleteCharAt()方法
//指定索引位置的字符
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
System.out.println( buffer.deleteCharAt(4));
结果:
abc中人def
delete()方法
//删除指定的区间
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
buffer.delete(4, 6);
System.out.println(buffer.toString());
结果:
abc中ef
insert()方法
//ffer.insert(offset, str) 插入操作
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
buffer.insert(0, "tom");
结果:
tomabc中国人def
substring()方法
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
//取出字串
System.out.println(buffer.substring(0, 3));
结果:
abc
reverse()方法
//反向操作
StringBuffer buffer=new StringBuffer();
buffer.append("abc中国人def");
System.out.println(buffer.reverse());
结果:
fed人国中cba
StringBuilder
基本操作方法与StringBuffer类似
在这里提及一下原来的setget方法
非builder模式
//就是我们之间setget类方法
class Demo{
private String name;
private int age ;
private boolean sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
在这种类下:我们调用时需要一个个调用
Person p=new Person();
p.setName("tom");
p.setAge(12);
p.setSex(1);
builder模式
与非builder模式不同的是我们在这里返回的是对象本身
public class Person {
private String name;
private int age ;
private boolean sex;
public String getName() {
return name;
}
public Person setName(String name) {
this.name = name;
return this;
}
public int getAge() {
return age;
}
public Person setAge(int age) {
this.age = age;
return this;
}
public boolean isSex() {
return sex;
}
public Person setSex(boolean sex) {
this.sex = sex;
return this;
}
在这种类下调用就可以逐渐累积:
即所谓的方法连编程
Person p=new Person().setName("tom").setAge(12);
在StringBuilder中我们就可以采用方法链编程
//返回是对象自身
StringBuilder builder =new StringBuilder();
builder.append("t")
.append("m")
.append("n");
StringBuffer和StringBuilder区别
最大区别:线程安全性问题
StringBuffer
对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全
的
public synchronized StringBuffer reverse() {
2 super.reverse();
3 return this;
4 }
5
6 public int indexOf(String str) {
7 return indexOf(str, 0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法
StringBuilder
并没有对方法进行加同步锁,所以是非线程安全
的。
StringBuffer是线程安全的
,这意味着它们已经同步方法来控制访问,以便只有一个线程可以在同一时间访问一个StringBuffer对象同步代码。因此,StringBuffer的对象通常在多线程环境中是安全的,使用多个线程可以试图同时访问相同StringBuffer对象。
StringBuilder
类非常相似的StringBuffer,不同之处在于它的访问不同步的,因此,它不是线程安全的。由于不同步,StringBuilder的性能可以比StringBuffer更好。因此,如果在单线程环境中工作,使用StringBuilder,而不是StringBuffer可能会有更高的性能。这也类似其他情况,如StringBuilder的局部变量(即一个方法中的一个变量),其中只有一个线程会访问一个StringBuilder对象。
StringBuffer和StringBuilder类的速度比较
4 final static int time = 50000; //循环次数
5 /*
6 * String类测试方法
7 */
8 public void test(String s){
9 long begin = System.currentTimeMillis();//获取当前系统时间(毫秒数),开始
10 for(int i=0; i<time; i++){
11 s += "add";
12 }
13 long over = System.currentTimeMillis();//获取当前系统时间(毫秒数),结束
14 System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒");
15 }
16 /*
17 * StringBuffer类测试方法
18 */
19 public void test(StringBuffer s){
20 long begin = System.currentTimeMillis();
21 for(int i=0; i<time; i++){
22 s.append("add");
23 }
24 long over = System.currentTimeMillis();
25 System.out.println("操作"+s.getClass().getCanonicalName()+"类型使用的时间为:"+(over-begin)+"毫秒");
26 }
27 /*
28 * StringBuilder类测试方法
29 */
30 public void test(StringBuilder s){
31 long begin = System.currentTimeMillis();
32 for(int i=0; i<time; i++){
33 s.append("add");
34 }
35 long over = System.currentTimeMillis();
36 System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒");
37
38
39
/*对 String 直接进行字符串拼接的测试*/
40 public void test2(){//操作字符串对象引用相加类型使用的时间
41 String s2 = "abcd";
42 long begin = System.currentTimeMillis();
43 for(int i=0; i<time; i++){
44 String s = s2 + s2 +s2;
45 }
46 long over = System.currentTimeMillis();
47 System.out.println("操作字符串对象引用相加类型使用的时间为:"+(over-begin)+"毫秒");
48 }
49 public void test3(){//操作字符串相加使用的时间
50 long begin = System.currentTimeMillis();
51 for(int i=0; i<time; i++){
52 String s = "abcd" + "abcd" + "abcd";
53 }
54 long over = System.currentTimeMillis();
55 System.out.println("操作字符串相加使用的时间为:"+(over-begin)+"毫秒");
56 }
57 public static void main(String[] args) {
58 // TODO Auto-generated method stub
59 String s1 = "abcd";
60 StringBuffer st1 = new StringBuffer( "abcd");
61 StringBuilder st2 = new StringBuilder( "abcd");
62 StringTest tc = new StringTest();
63 tc.test(s1);
64 tc.test(st1);
65 tc.test(st2);
66 tc.test2();
67 tc.test3();
68 }
69 }
从上面的结果可以看出,不考虑多线程,采用String对象时,执行时间比其他两个都要高得多,而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显;而以String类为例,操作字符串对象引用相加类型使用的时间比直接/操作字符串相加使用的时间也多得多。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer;能直接操作字符串不用字符串引用就直接操作字符串。
总结:
在这方面运行速度快慢为:StringBuilder > StringBuffer > String
(1).如果要操作少量的数据用 = String
(2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
(3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer