⭐写在前面⭐
今天我们进行 Java StringBuffer和StringBuilder 的学习,感谢你的阅读,内容若有不当之处,希望大家多多指正,一起进步!!!
♨️如果觉得博主文章还不错,可以三连支持⭐一下哦
java.lang.StringBuffer代表可变字符序列,可以对字符串内容进行增删,此时不会产生新的对象。
很多方法与String相同。
StringBuffer
是一个容器。
作为方法传递时,方法内部可以改变值。
StringBuffer
是一个final类,不可被继承。
实现了Serializable
接口,支持序列化,可以保存到文件,或者进行网络传输。
继承自抽象类AbstractStringBuilder
,因为Stringbuffer字符内容是存放在char[] value,所以在变化(增加/删除)不用每次创建新的对象,所以效率高于String。
作为方法传递时,方法内部可以改变值。
String
保存的是字符串常量,里面的值不可以更改,每次String类的更新其实就是创建了一个新的对象,更新了地址,效率极低。
StringBuffer
保存的是字符串常量,里面的值可以更改,每次StringBuffer的更新其实就是在原有的字符串上进行修改,不用每次更新了地址,效率较高。
StringBuffer
类不同于String,其对象必须使用构造器生成,不能用字面量的方式赋值。有三个构造器:
在实例化时如果不指定容量就默认初始化大小为16
在实例化时如果指定字符串内容大小就为字符串的长度 + 16
如果容量不够就进行原有容量乘以2倍再加2扩容
@Test
public void test01() {
StringBuffer sb = new StringBuffer("abc");
StringBuffer abc = sb.append("abc");
StringBuffer append = sb.append(5);
sb.append(true);
System.out.println(sb);
}
append、delete、replace、insert、reverse方法,支持 方法链 操作。
方法链原理:
例如:
StringBuffer delete(int start,int end): 删除指定位置的内容。
@Test
public void test02() {
StringBuffer sb = new StringBuffer("abcdefg");
sb.delete(2,5);
System.out.println(sb);
}
StringBuffer replace(int start,int end,String str): 把[start,end)位置的内容替换为str。
@Test
public void test03() {
StringBuffer sb = new StringBuffer("abcdefg");
sb.replace(2,5,"hello");
System.out.println(sb);
}
StringBuffer insert(int offset,xxx): 在指定位置插入xxx。
@Test
public void test04() {
StringBuffer sb = new StringBuffer("abcd");
sb.insert(2,"hello");
System.out.println(sb);
}
StringBuffer reverse(): 把当前字符序列逆转。
@Test
public void test05() {
StringBuffer sb = new StringBuffer("abcdefg");
sb.reverse();
System.out.println(sb);
}
方式一:使用构造器
@Test
public void test01() {
String s = new String("abc");
StringBuffer sb = new StringBuffer(s);
System.out.println(sb);
}
方式二:使用append方法
@Test
public void test02() {
String s = new String("abc");
StringBuffer sb = new StringBuffer();
sb.append(s);
System.out.println(sb);
}
方式一:使用 StringBuffer提供的toString方法
@Test
public void test03() {
StringBuffer sb = new StringBuffer("hello");
String s = sb.toString();
System.out.println(s);
}
方式一:使用String构造器
@Test
public void test04() {
StringBuffer sb = new StringBuffer("hello");
String s = new String(sb);
System.out.println(s);
}
看这样一段代码
public class StringBufferTest {
public static void main(String[] args) {
String str = null;
StringBuffer sb1 = new StringBuffer();
sb1.append(str);
System.out.println(sb1.length());
System.out.println(sb1);
System.out.println("**********************************");
StringBuffer sb2 = new StringBuffer(str);
System.out.println(sb2);
}
}
当调用append方法,字符串为null时,会把null作为字符串“null”进行拼接。
底层调用
AbstractStringBuilder
中的appendNull方法。
当实例化StringBuffer用null作为构造器的参数时会抛出NullPointerException
异常。
StringBulider
和StringBuffer非常类似,均代表可变字符序列。此类提供了一个与StringBuffer兼容的API,其方法和StringBuffer类似,但不保证同步(StringBuilder的方法没有synchronized关键字修饰,因此是线程不安全的)
该类被设计用作StringBuffer的一个简易替换, 用在字符缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数的实现中,它比StringBuffer要快。
分别用
String
、StringBuffer
和StringBuilder
进行同样的20000次拼接,比较三者所用的时间。
@Test
public void stringVsStringBufferVsStringBuilder() {
long startTime = 0L;
long endTime = 0L;
String s = "";
StringBuffer sb1 = new StringBuffer();
StringBuilder sb2 = new StringBuilder();
startTime = System.currentTimeMillis();
for (int i = 0;i < 20000;i++) {
s += i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间: " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0;i < 20000;i++) {
sb1.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间: " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0;i < 20000;i++) {
sb2.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间: " + (endTime - startTime));
}
结论