StringBuffer与StringBuild

StringBuffer结构解析

  • 我们查看以下的结果,可以看出StringBuffer的父类以及相应的接口,表示该对象可以进行串行化以及可以用来比较

image-20220301193814501

  • 我们查看StringBuffer的父类AbstractStringBuilder,可以看到源码中存在着byte[] value,而且不是final类型,而该value数组存放着我们的字符串内容,因此可以了解到该字符存放在堆中,并不是存放在常量池中,所以对比前面学到的String,String保存的是字符串常量,里面的值并不能更改,每次更改需要改变地址。而StringBuffer保存的是字符串变量,里面的值可以更改,每一次更新实际可以更新内容,不用每一次更新地址(到我们的地址指向的空间不够时,地址才会改变),效率比较高。

image-20220301194352958

  • StringBuffer是一个final类,并不能被继承

StringBuffer的转换

  • StringBuffer的构造方法

image-20220301195420797

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public StringBuffer() {
super(16);
}
//创建一个大小为16的char[]数组,用于存放字符内容
StringBuffer stringBuffer = new StringBuffer();

public StringBuffer(int capacity) {
super(capacity);
}
//创建一个初始容量为100的char[]数组
StringBuffer stringBuffer = new StringBuffer(100);

public StringBuffer(String str) {
super(str);
}
//创建一个容量为stringBuffer.length+16的char[]数组,用于存放字符
StringBuffer stringBuffer = new StringBuffer("ascvcacv");


public StringBuffer(CharSequence seq) {
super(seq);
}

  • String与StringBuffer相互转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package Learn;

import java.util.Arrays;
import java.util.Locale;

public class Test {
public static void main(String[] args) {
//string转换为StringBuffer
String str="hello";
//方法1:使用构造器,对str本身没有影响
StringBuffer stringBuffer1=new StringBuffer(str);
//方法2:使用append的方法
StringBuffer stringBuffer2=stringBuffer1.append(str);


//StringBuffer转换为String
StringBuffer stringBuffer=new StringBuffer("java");
//方法1:tostring
String str1=stringBuffer.toString();
//方法2:使用构造器
String str2=new String(stringBuffer);
}
}

StringBuffer的常见方法

方法名 用法
append
delete
replace
indexOf
insert 插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package Learn;

public class Test {
public static void main(String[] args) {
StringBuffer stringBuffer=new StringBuffer("java");
stringBuffer.append("ee");
System.out.println(stringBuffer);
stringBuffer.delete(4,6);
System.out.println(stringBuffer);
stringBuffer.replace(0,1,"ha");
System.out.println(stringBuffer);
System.out.println(stringBuffer.indexOf("v"));
stringBuffer.insert(1,"ha");
System.out.println(stringBuffer);
}
}

image-20220301201856495

练习:

一步一步调试,追溯源码,可以看出最终两个的差别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package Learn;

public class Test {
public static void main(String[] args) {
String str=null;
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append(str);
System.out.println(stringBuffer.length());
System.out.println(stringBuffer);

StringBuffer stringBuffer1=new StringBuffer(str);
System.out.println(stringBuffer1.length());

}
}

image-20220301202739437

学会利用StringBuffer格式化输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package Learn;

import java.util.Scanner;

public class Test {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String name=scanner.next();
String price=scanner.nextDouble()+"";
StringBuffer price1=new StringBuffer(price);
int i=price1.lastIndexOf(".");
while (i>=3){
price1.insert(i-3,",");
i=i-3;
}
System.out.println(price1);

}
}

image-20220301204926140

StringBuilder结构剖析

  1. StringBuilder是一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但是不保证同步(StringBuilder不是线程安全的,所有的方法都没有做互斥处理)。该类被设计用作StringBuffer的一个简易的替换,用在字符串缓冲区被单个线程使用时候,可以优先采用此类,大多数线程中比StringBuffer快
  2. 下面的图表明StringBuilder与StringBuffer继承了相同的类与接口,StringBuilder也是final的,不可以被继承

image-20220301205717395

StringBuilder速度比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package Learn;

import java.util.Scanner;

public class Test {
public static void main(String[] args) {
StringBuffer stringBuffer=new StringBuffer("花花");
long startTime=System.currentTimeMillis();
for (int i=0;i<2000;i++){
stringBuffer=stringBuffer.append("haha");
}
long endTime=System.currentTimeMillis();
long totalTime=endTime-startTime;
System.out.println("时间为"+totalTime);

StringBuilder stringBuilder=new StringBuilder("花花");
startTime=System.currentTimeMillis();
for (int i=0;i<2000;i++){
stringBuilder=stringBuilder.append("haha");
}
endTime=System.currentTimeMillis();
totalTime=endTime-startTime;
System.out.println("时间为"+totalTime);
}
}


image-20220301211620315

String,StringBuffer与StringBuilder比较

  1. StringBuffer与StringBuilder非常类似,均可以表示可变的字符序列,方法也一样
  2. String不可变的字符序列,效率低,复用性高,如果我们对String做大量的修改,不要使用String
  3. StringBuffer可变的字符序列,效率比较高,线程安全
  4. StringBuilder可变,效率最高,线程不安全