您的位置:首页 > 健康 > 美食 > 爱站关键词_上海企业网络推广方案_php开源建站系统_扫一扫识别图片

爱站关键词_上海企业网络推广方案_php开源建站系统_扫一扫识别图片

2025/4/3 12:46:26 来源:https://blog.csdn.net/2401_89019969/article/details/146641236  浏览:    关键词:爱站关键词_上海企业网络推广方案_php开源建站系统_扫一扫识别图片
爱站关键词_上海企业网络推广方案_php开源建站系统_扫一扫识别图片

StringBuilder和StringBuffer

  • 字符串的不可变性
  • 字符串修改
  • StringBuilder和StringBuffer
    • 1 字符串拼接
    • 2 获取、修改和删除下标字符
    • 3 插入字符
    • 4 字符串替换
    • 5 字符串反转
    • 6 StringBuffer和StringBuilder类与String类的转换
  • StringBuffer和StringBuilder类的区别

前言
在Java中String是⼀种不可变对象.字符串中的内容是不可改变,有时候修改成功其实是创建临时变量,但有时候修改次数过多的话,就会影响代码的效率,所以Java提供了StringBuilder和StringBuffer用来修改字符串内容

字符串的不可变性

String是⼀种不可变对象,字符串中的内容是不可改变,字符串不可被修改

下面是JDK17中String的部分源码
在这里插入图片描述
在String源码中其实被final修饰的,final修饰的是常量,所以不可以修改,并且其内部有私有成员,因此其并不是真正的修改内容,String的不可变性质

字符串修改

public class Test {public static void main(String[] args) {String s = "abc";s = s +"def";System.out.println(s);}
}

运行结果如下
在这里插入图片描述
上面说其不可以被修改,为什么这里的结果却修改了呢,其实这里本质是创建了临时变量,其实是对新对象的修改,并不是修改了原本的对象
,因此这样的修改创建临时变量会影响代码的效率

我们从下面这个代码来直观的感受其效率

public static long currentTimeMillis()
返回值是:long长类型
功能:获取当前的时间,单位是毫秒

在这里插入图片描述

public class Test {public static void main(String[] args) {//获取当前时间long start = System.currentTimeMillis();String s = "";for (int i = 0; i < 10000; i++) {s+=i;}//循环结束的时间long end = System.currentTimeMillis();//相减就得到了,这个创建临时变量循环的时间System.out.println(end-start);}
}

这样我们使用一个循环来判断其所创建临时变量所浪费的时间,获取进入循环的时间和结束循环的时间,二者相减就获得了经过循环的时间
运行结果如下
在这里插入图片描述
这个效率其实是很慢的,这时候就要引入[StringBuilder]和[StringBuffer]

public class Test {public static void main(String[] args) {//获取当前时间//Stringlong start = System.currentTimeMillis();String s = "";for (int i = 0; i < 10000; i++) {s += i;}//循环结束的时间long end = System.currentTimeMillis();//相减就得到了,这个创建临时变量循环的时间System.out.println("String的时间:"+(end - start));//StringBuilderlong start1 = System.currentTimeMillis();StringBuilder stringBuilder = new StringBuilder("");for (int i = 0; i < 10000; i++) {stringBuilder.append(i);//拼接}long end1 = System.currentTimeMillis();System.out.println("StringBuilder的时间:"+(end1-start1));//StringBufferlong start2 = System.currentTimeMillis();StringBuffer stringBuffer = new StringBuffer("");for (int i = 0; i <10000 ; i++) {stringBuffer.append(i);}long end2 = System.currentTimeMillis();System.out.println("StringBuffer的时间:"+(end2-start2));}
}

运行结果如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
虽然这个运行速率有所改变,但是这里的StringBuffer与StringBuilder的速率相近并且接近于0,String类的速率较慢
从结果中可以看出可以看到在对String类进⾏拼接时,效率是⾮常慢,因此:尽量避免对String的直接需要,如果要修改建议尽量使⽤StringBuffer或者StringBuilder

StringBuilder和StringBuffer

StringBuilder和StringBuffer与String使用类似,但是也有一些其String没有的方法

方法说明
StringBuffer append(String str)尾部追加
char charAt(int index)获取index下标的字符
int length()获取字符串长度
int capacity()获取底层保存字符串空间
ensureCapacity(int minimumCapacity)扩容
setCharAt(int index, char ch)将index下标字符改为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int fromIndex)从fromIndex下标开始找str第一次出现的位置
int lastIndexOf(String str)从后向前找返回str第一次出现的位置
int lastIndexOf(String str, int fromIndex)从最后到fromIndex下标开始找str第一次出现的位置
StringBuffer insert(int offset, String c)在offset插入:八种基本类型与String类
StringBuffer deleteCharAt(int index)删除index下标字符
StringBuffer delete(int start, int end)删除从[start,end)下标字符
StringBuffer replace(int start, int end, String str)将[start,end)下标字符替换为str
String substring(int start)从start下标开始一直到末尾存储到一个新的String类中
String substring(int start, int end)[start,end)下标存储到一个新的String类中
StringBuffer reverse()将字符串进行反转
String toString()将所有字符按照String方式返回

这里的StringBuilder和StringBuffer方法类似,所以下面只以StringBuffer举例

1 字符串拼接

append(String str)
将str字符串拼接到后面
这个可以将基本八种类型&String类型都可以进行拼接

在这里插入图片描述

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("");stringBuffer.append(" ");stringBuffer.append("hello");System.out.println(stringBuffer);StringBuilder stringBuilder = new StringBuilder("");stringBuilder.append(" ");stringBuilder.append("hello");System.out.println(stringBuilder);}
}

运行结果如下
在这里插入图片描述

2 获取、修改和删除下标字符

1.获取下标字符

char charAt(index)
获取index下标字符
返回char类型

 StringBuffer stringBuffer = new StringBuffer("abc");char ch = stringBuffer.charAt(1);System.out.println(ch);

运行结果如下
在这里插入图片描述
2.修改下标字符

char setCharAt(index)
获取index下标字符
返回void类型

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("abc");System.out.println("修改前:"+stringBuffer.charAt(1));// - 获取1下标的字符--’b'stringBuffer.setCharAt(1,'m');//修改1下标字符System.out.println("修改后:"+stringBuffer.charAt(1));}
}

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/439b2d1af305453c8aae015d8a2cc563.png
)
注意:这里由于返回的是void类型,所以这里只是对 StringBuffer修改,不可以直接打印
如果直接打印其修改过程,编译器就会报错
在这里插入图片描述
3.删除下标字符

deleteCharAt(int index)删除index下标字符
deleteCharAt(int start,int end)删除[start,end)下标字符
返回值都是void

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("abcdef");System.out.println("修改前:"+stringBuffer.charAt(1));// - 获取1下标的字符--’b'stringBuffer.setCharAt(1,'m');//修改1下标字符System.out.println("修改后1下标后:"+stringBuffer);stringBuffer.deleteCharAt(1);//删除指定下标System.out.println("删除1下标后:"+stringBuffer);//删除下标区间的字符stringBuffer.delete(1,5);System.out.println("删除[1,5)下标字符后:"+stringBuffer);}
}

这里首先打印1下标字符,其次修改1下标字符为’m’,其次删除1下标字符,最后删除[1,5)下标字符后的stringBuffer
在这里插入图片描述

3 插入字符

insert(int offset, String str)
在offset插入字符串str
这里的str需要插入的可以是基本八种类型和String类
但是本质还是将其转化为字符串表示形式进行插入

在这里插入图片描述在这里插入图片描述

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("aaaaa");stringBuffer.insert(1,"___");System.out.println(stringBuffer);stringBuffer.insert(3,3.12);System.out.println(stringBuffer);}
}

第一次是从1下标开始插入_ _ _
第二次会在其基础上的从3下标开始插入3.12,虽然是double类型,其实本质还是插入字符串类型
在这里插入图片描述

4 字符串替换

replace(int start, int end, String str)
将[start,end)下标字符替换为字符串str
如果str长度<这个区间的长度,从前向后替换,替换后多余的变成“”空白,字符串内容会减少
如果str长度>这个区间长度,编译器会自动扩容把这个字符串全部放进去,只修改[start,end)区间的字符,其他的不会修改

str字符串长度等于[start,end)区间长度

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("aaaaaa");System.out.println("原本其长度:"+stringBuffer.length());stringBuffer.replace(0,4,"AAAA");System.out.println(stringBuffer);System.out.println("取代后长度:"+stringBuffer.length());}
}

这里取代的字符串长度是等于[0,4)这个区间的大小的,都是为4,这是正常取代
原本字符串长度没有改变
在这里插入图片描述

str字符串长度小于[start,end)区间长度

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("aaaaaa");System.out.println("原本其长度:"+stringBuffer.length());stringBuffer.replace(0,4,"AA");System.out.println(stringBuffer);System.out.println("取代后长度:"+stringBuffer.length());}
}

这里我们是准备将[0,4)区间的字符替换为str的,但是这个str长度小于[start,end)区间长度
这个时候在取代的时候,编译器会将其区间替换,可以理解为多余的会变成”“空白
这里相当于 ”AA"替换4个位置,从前向后,多的就直接相当于空
这时候编译器会自动减小字符串长度
在这里插入图片描述
str字符串长度大于[start,end)区间长度

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("aaaaaa");System.out.println("原本其长度:"+stringBuffer.length());stringBuffer.replace(0,4,"AAAAAAAAAAA");System.out.println(stringBuffer);System.out.println("取代后长度:"+stringBuffer.length());}
}

这时候str字符串长度大于[0,4)区间长度,它不管你是否够方下,它直接将这些字符全部放在从start下标开始,直到放完结束,[0,4)下标以外的字符不会修改,只是下标可能变了,其实这里相当于给字符串扩容了
在这里插入图片描述

5 字符串反转

reverse()字符串反转

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("hello");System.out.println("反转前:"+stringBuffer);stringBuffer.reverse();System.out.println("反转后:"+stringBuffer);}
}

在这里插入图片描述

6 StringBuffer和StringBuilder类与String类的转换

直接转化的话是不可以的,编译器会报错
在这里插入图片描述

**toString()**方法将StringBuffer类转化为String类

public class Test {public static void main(String[] args) {StringBuffer stringBuffer = new StringBuffer("bbb");StringBuilder stringBuilder = new StringBuilder("ccc");String string = new String("aaa");//将其转化为String赋值string = stringBuffer.toString();System.out.println(string);string = stringBuilder.toString();System.out.println(string);}
}

运行结果如下,这里是不可以直接赋值,需要使用toString方法转化为String类
在这里插入图片描述

StringBuffer和StringBuilder类的区别

StringBuffer和StringBuilder从⽅法的功能上来说没有太⼤区别
但是二者方法内部有区别

在这里插入图片描述

StringBuffer和StringBuilder类的区别
1 方法功能都是一样的
2 其 StringBuffer类中的方法,前面多了一个synchronized修饰,这个相当于一个锁,有人使用就把锁锁上,使用完离开就将锁打开
3 因此StringBuffer是同步处理,是线程安全的,而StringBuilder类没有采取同步处理,线程不安全

到这里就结束了,预知后事如何,请听下回分解

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com