java_StringBuilder和StingBuffer

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

发布了50 篇原创文章 · 获赞 75 · 访问量 6688

猜你喜欢

转载自blog.csdn.net/weixin_45822638/article/details/103855169