⭐写在前面⭐
📢今天我们进行 Java StringBuffer和StringBuilder 的学习,感谢你的阅读,内容若有不当之处,希望大家多多指正,一起进步💯!!!
♨️如果觉得博主文章还不错,可以👍三连支持⭐一下哦😀
每一个不曾起舞的日子,都是对生命的辜负 。—尼采
文章目录
☘️Java StringBuffer和StringBuilder
🍀StringBuffer类
🌱 java.lang.StringBuffer代表可变字符序列,可以对字符串内容进行增删,此时不会产生新的对象。
🌱 很多方法与String相同。
🌱StringBuffer
是一个容器。
🌱作为方法传递时,方法内部可以改变值。
🌱
StringBuffer
是一个final类,不可被继承。
🌱 实现了Serializable
接口,支持序列化,可以保存到文件,或者进行网络传输。
🌱继承自抽象类AbstractStringBuilder
,因为Stringbuffer字符内容是存放在char[] value,所以在变化(增加/删除)不用每次创建新的对象,所以效率高于String。
🌱作为方法传递时,方法内部可以改变值。
🌿StringBuffer VS String
🌱
String
保存的是字符串常量,里面的值不可以更改,每次String类的更新其实就是创建了一个新的对象,更新了地址,效率极低。
🌱
StringBuffer
保存的是字符串常量,里面的值可以更改,每次StringBuffer的更新其实就是在原有的字符串上进行修改,不用每次更新了地址,效率较高。
🌱
StringBuffer
类不同于String,其对象必须使用构造器生成,不能用字面量的方式赋值。有三个构造器:
🍁在实例化时如果不指定容量就默认初始化大小为16
🍁在实例化时如果指定字符串内容大小就为字符串的长度 + 16
🍁如果容量不够就进行原有容量乘以2倍再加2扩容
🌿StringBuffer类常用方法
🌱 StringBuffer append(xxx): 提供了很多的append方法,用于字符串的拼接。
@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);
}
运行结果:
🌿StringBuffer和String相互转换
🍃String➡️StringBuffer
🌱方式一:使用构造器
@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➡️String
🌱方式一:使用 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);
}
运行结果:
🌿StringBuffer与null
看这样一段代码
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
异常。
🍀StringBuilder类
🌱
StringBulider
和StringBuffer非常类似,均代表可变字符序列。此类提供了一个与StringBuffer兼容的API,其方法和StringBuffer类似,但不保证同步(StringBuilder的方法没有synchronized关键字修饰,因此是线程不安全的)
🌱该类被设计用作StringBuffer的一个简易替换, 用在字符缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数的实现中,它比StringBuffer要快。
🍀String、 StringBuffer 和 StringBuilder 的比较
🌿三者区别
🌿三者效率比较
分别用
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));
}
运行结果:
🍁结论
三者的效率从小到大为: