String、StringBuffer和StringBuilder的区别:

String

  String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。

  这个是String类的解释,之前童鞋看到这个情况,不能理解上述的解释,如下

String a = "123";
a = "456";
// 打印出来的a为456
System.out.println(a)

看到这里,不明白了,这不是明明已经对他进行修改了吗?为什么还说他是一个不可变类呢?

经过和小伙伴们的学习,明白String类不可变在哪里体现出来的,接下来就看一张上述a对象的内存存储空间图

可以看出来,再次给a赋值时,并不是对原来堆中实例对象进行重新赋值,而是生成一个新的实例对象,并且指向“456”这个字符串,a则指向最新生成的实例对象,之前的实例对象仍然存在,如果没有被再次引用,则会被垃圾回收。

StringBuffer
  StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象

StringBuffer b = new StringBuffer("123");
b.append("456");
// b打印结果为:123456
System.out.println(b);

  在看一下b对象的内存空间图:

 所以说StringBuffer对象是一个字符序列可变的字符串,它没有重新生成一个对象,而且在原来的对象中可以连接新的字符串。

注意:既然定义字符串可以使用String或者StringBuffer类,那我们如何选择?若在程序中,需要经常增加,删除,或者替换字符串,使用StringBuffer类可以轻松应对。如果只是静态使用字符串,String类是个很好的选择

扩展:StringBuffer 方法

以下是 StringBuffer 类支持的主要方法:

序号方法描述
1

public StringBuffer append(String s)
将指定的字符串追加到此字符序列。

注意:append只能在字符串后面追加内容,insert()方法可以将内容插入到字符串任意位置

2 public StringBuffer reverse()
 将此字符序列用其反转形式取代。
3

public delete(int start, int end)
移除此序列的子字符串中的字符。

如果删除指定位置单个字符,deleteCharAt()方法

4 public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。(第二个参数可以是字符串)
5 replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。

下面的列表里的方法和 String 类的方法类似:

 

序号方法描述
1 int capacity()
返回当前容量。默认容量为16字符
2 char charAt(int index)
返回此序列中指定索引处的 char 值。
3 void ensureCapacity(int minimumCapacity)
确保容量至少等于指定的最小值。
4 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此序列复制到目标字符数组 dst
5 int indexOf(String str)
返回第一次出现的指定子字符串在该字符串中的索引。
6 int indexOf(String str, int fromIndex)
从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。
7 int lastIndexOf(String str)
返回最右边出现的指定子字符串在此字符串中的索引。
8 int lastIndexOf(String str, int fromIndex)
返回 String 对象中子字符串最后出现的位置。
9 int length()
 返回长度(字符数)。
10 void setCharAt(int index, char ch)
将给定索引处的字符设置为 ch若超过指定的字符串长度则将其截除
11 void setLength(int newLength)
设置字符序列的长度。
12 CharSequence subSequence(int start, int end)
返回一个新的字符序列,该字符序列是此序列的子序列。
13 String substring(int start)
返回一个新的 String,它包含此字符序列当前所包含的字符子序列。
14 String substring(int start, int end)
返回一个新的 String,它包含此序列当前所包含的字符子序列。
15

String toString()
返回此序列中数据的字符串表示形式。

注意:StringBuffer类没有重写Object类的equals()方法,所以StringBuffer类不能使用equals()方法比较StringBuffer值,应当使用toString()方法将SringBuffer的内容转换为String字符串,再使用equals()方法比较

提示:(1)StringBuffer的capacity()方法返回的容量和length()方法返回的字符串长度,不止在数值上不同,含义上也不同。

            (2)

StringBuffer类可以创建可修改的字符串序列。该类有StringBuffer(),StringBuffer(int size),StringBuffer(String s)三个改造方法。

1、StringBuffer()的初始容量可以容纳16个字符,当该对象的实体存放的字符的长度大于16时,实体容量就自动增加。StringBuffer对象可以通过length()方法获取实体中存放的字符序列长度,通过capacity()方法来获取当前实体的实际容量。

2、StringBuffer(int size)可以指定分配给该对象的实体的初始容量参数为参数size指定的字符个数。当该对象的实体存放的字符序列的长度大于size个字符时,实体的容量就自动的增加。以便存放所增加的字符。增长规律:(容量+1)*2

3、StringBuffer(String s)可以指定给对象的实体的初始容量为参数字符串s的长度额外再加16个字符。当该对象的实体存放的字符序列长度大于size个字符时,实体的容量自动的增加,以便存放所增加的字符。如果按照增长规律后还是不够

     那么它的容量就等于字符串的长度。(见Java编程手记   欧二强等编著)

StringBuilder
  StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高

StringBuffer是如何实现线程安全的呢?
StringBuffer类中实现的方法:

 StringBuilder类中实现的方法:

由此可见,StringBuffer类中的方法都添加了synchronized关键字,也就是给这个方法添加了一个锁,用来保证线程安全。

Java9的改进
  Java9改进了字符串(包括String、StringBuffer、StringBuilder)的实现。在Java9以前字符串采用char[]数组来保存字符,因此字符串的每个字符占2字节;而Java9的字符串采用byte[]数组再加一个encoding-flag字段来保存字符,因此字符串的每个字符只占1字节。所以Java9的字符串更加节省空间,字符串的功能方法也没有受到影响

参考链接:https://blog.csdn.net/csxypr/article/details/92378336

posted @ 2021-03-28 14:07  Chen洋  阅读(348)  评论(0编辑  收藏  举报