目录
⛳️概述
⛳️StringBuffer和StringBuilder中常用的方法
1.构造方法
2.添加功能
3.删除功能
4.替换功能
5.反转功能
6.截取功能
7.获取功能
⛳️String、StringBuffer、StringBuilder的异同
1.相同点
2.不同点
都是可变的字符序列,我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时又浪费空间,这个时候就需要使用StringBuffer或StringBuilder来解决这个问题,当需要考虑线程安全的场景下,使用StringBuffer,如果不需要考虑线程安全,追求效率的情况下,可以使用StringBuilder
对可变的的理解:
案例:
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcd");长度为20
//向末尾追加内容
stringBuffer.append("efg111111");//加进去长度还没有超过20
stringBuffer.append("efg222222");//加进去长度超过20,此时就要重新创建底层的数组
}
}
以debug模式运行:
①开始时StringBuffer的地址值是487,value数组是492
②当count是13时两个地址值都没有变
③此时StringBuffer的地址仍然是487,而value数组变成了497
所以当向StringBuffer中添加内容时,是将内容添加到底层的数组中,数组没有被final修饰,变的是底层数组(char[] value),而不是StringBuffer对象,当数组装满时,会创建一个新的数组,将新数组地址给底层数组,StringBuffer对象是不会改变的
StringBuffer、StringBuilder和String类似,底层也是用char数组来存储字符串的值,并且数组的默认长度为16,即一个空的StringBuffer对象数组长度为16,实例化一个StringBuffer对象即创建了一个大小为16个字符的字符串缓冲区,但是当我们调用有参构造函数创建一个StringBuffer对象时,数组长度就不再是16了,而是根据当前对象的值来决定数组的长度,数组的长度=当前对象字符串的长度+16;所以一个StringBuffer创建完成之后,有16个字符空间可以对其值进行修改,修改的时候,会先判断StringBuffer对象原来的char数组的容量能不能装下新的字符串,如果装不下则会对char数组进行扩容
①public StringBuffer()
构造一个没有字符的字符缓冲区,初始容量为16个字符
②public StringBuffer(String str)
构造一个初始化为指定字符串内容的字符串缓冲区
长度为字符串长度加默认长度(16)
③public StringBuffer(int capacity)
构造一个指定初始容量的没有字符的字符缓冲区
①public StringBuffer append(String str)
拼接字符串
②public StringBuffer insert(int offset,String str)
在指定位置插入指定的内容
案例:
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcd");
//向末尾追加内容
stringBuffer.append("efg111");
System.out.println(stringBuffer);//abcdefg111
StringBuffer stringBuffer1 = new StringBuffer("abcd");
//向指定的位置插入字符串
stringBuffer1.insert(2,"xx");
System.out.println(stringBuffer1);//abxxcd
}
}
①public StringBuffer deleteCharAt(int index)
删除指定位置的内容
②public StringBuffer delete(int start,int end)
删除指定范围的内容,左闭右开
案例:
public class StringBufferDemo1 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcd");
//删除指定位置的内容
stringBuffer.deleteCharAt(1);
System.out.println(stringBuffer);//acd
StringBuffer stringBuffer1 = new StringBuffer("abcdefg");
//删除指定区间的内容,包含开始,不包含结束
stringBuffer.delete(0,3);
System.out.println(stringBuffer1);//defg
}
}
public StringBuffer replace(int start,int end,String str)
替换指定范围的内容
案例:
public class StringBufferDemo2 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcdefg");
//替换
stringBuffer.replace(2,5, "XXX");
System.out.println(stringBuffer);//abXXXfg
}
}
public StringBuffer reverse()
把当前字符串序列逆转
案例:
public class StringBufferDemo3 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcdefg");
//逆序字符串
stringBuffer.reverse();
System.out.println(stringBuffer);//gfedcba
}
}
①public String substring(int start)
截取一个字符串副本返回
②public String substring(int start,int end)
返回指定范围的子字符串
截取功能和前面几个功能的不同,返回值类型是String类型,不是直接在数组上操作的,是在原来的串上截取了一段,赋给了一个新的字符串,相当于截取了一个副本回来,原来的字符串不变
案例:
public class StringBufferDemo4 {
public static void main(String[] args) {
StringBuffer stringBuffer1 = new StringBuffer("abcdefg");
//截取一个字符串副本返回
String sub = stringBuffer1.substring(2);
System.out.println(sub);//cdefg
//stringBuffer不变
System.out.println(stringBuffer1);//abcdefg
StringBuffer stringBuffer2 = new StringBuffer("qwertyu");
//截取一个字符串副本返回
String sub = stringBuffer.substring(2,5);
System.out.println(sub);//ert
//stringBuffer不变
System.out.println(stringBuffer);//qwertyu
}
}
int length()
返回底层数组中实际装入的字符个数
案例:
public class StringBufferDemo4 {
public static void main(String[] args) {
String s1 = "qwer";
System.out.println(s1.length());//4
//返回的是底层数组中实际装入的字符个数
StringBuffer stringBuffer = new StringBuffer("qwqqwqw");
System.out.println(stringBuffer.length());//7
}
}
StringBuilder类功能和StringBuffer功能完全一致,有区别的是StringBuffer是线程安全的
方法实现(源码):
StringBuilder方法实现:
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
StringBuffer方法实现:加上了synchronized同步锁,一次只允许一个线程进入方法操作,不允许两个线程同时进入操作
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
StringBuffer和StringBuilder常用方法总结:
StringBuffer append(xxx):拼接字符串
StringBuffer delete(int start,int end):删除指定范围的内容,左开右闭
StringBuffer replace(int start, int end, String str):替换指定范围的内容
StringBuffer insert(int offset, xxx):在指定位置插入指定的内容
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str) : 返回指定子字符串在当前字符串中第一次出现处的索引
public String substring(int start,int end) :返回指定范围的子字符串
public int length() : 返回字符串的长度
public char charAt(int n ) : 获取指定索引处的字符
public void setCharAt(int n ,char ch) : 设置指定索引处的字符
String:适用于少量的字符串操作的情况
StringBuffer:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuilder:适用多线程下在字符缓冲区进行大量操作的情况
底层都是通过char数组实现的
String对象一旦创建,其值不能改变,如果要修改,会重新开辟内存空间来修改存储之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的
StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率较低;而StringBuilder没有实现同步,线程不安全,在多线程系统中不能使用StringBuilder,但是效率比较高
在实际开发中,如果需要对字符串进行频繁的修改,就要避免使用String,否则会造成内存空间浪费,当需要考虑线程安全的场景下,使用StringBuffer,如果不需要考虑线程安全,追求效率的情况下,可以使用StringBuilder