StringBuilder

StringBuilder类

  • 查阅java.lang.StringBuilder的API,StringBuilder又称为可变字符序列,它是一个类似于 String 的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。
  • 原来StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。
  • 它的内部拥有一个数组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容。StringBuilder会自动维护数组的扩容。默认16字符空间,超过自动扩充

解决字符串拼接问题

在API中对String类有这样的描述:字符串是常量,它们的值在创建后不能被更改

1
2
3
4
5
6
7
// 拼接字符串
String str1 = "Hello";
String str2 = "World";
String str3 = str1.concat(str2);
System.out.println(str1); // Hello,原封不动
System.out.println(str2); // World,原封不动
System.out.println(str3); // HelloWorld,新的字符串

根据这句话分析我们的代码,其实总共产生了三个字符串,即`”Hello”,”World”和”HelloWorld”

引用变量s首先指向Hello对象,最终指向拼接出来的新字符串对象,即HelloWord

由此可知,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。为了解决这一问题,可以使用java.lang.StringBuilder类。

img

String、StringBuffer、StringBuilder 的区别?

可变性

String 是不可变的,String类和char数组都被被final修饰,每次修改String的值都会产生一个新的对象

StringBuilderStringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 finalprivate 关键字修饰,最关键的是这个 AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。

线程安全性

String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilderStringBuilderStringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacityappendinsertindexOf 等公共方法。**StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的**。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

存储

String存储在字符串常量池里面,而Stringbuilder和StringBuffer存储在堆内存里卖弄

对于三者使用的总结:

  1. 操作少量的数据: 适用 String
  2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
  3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

StringBuilder相关方法

构造方法

**public StringBuilder()**:构造一个空的StringBuilder容器

**public StringBuilder(String str)**:构造一个StringBuilder容器,并将字符串添加进去

1
2
3
4
5
6
7
8
//空参数构造方法
StringBuilder bu1 = new StringBuilder();
System.out.println("bu1:"+ bu1);// bu1:""


//带字符串的构造方法
StringBuilder bu2 = new StringBuilder("abc");
System.out.println("bu2:" + bu2);//bu2:abc

append方法

**public StringBuilder append()**:添加任意类型数据的字符串形式,并返回当前对象自身。

  • append方法具有多种重载形式,可以接收任意类型的参数。
  • 任何数据作为参数都会将对应的字符串内容添加到StringBuilder中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//创建StringBuilder对象
StringBuilder bu1 = new StringBuilder();

//使用append方法往StringBuilder中添加数据
append方法返回的是this,调用方法的对象b1,this==bu1
StringBuilder bu2 = bu1.append("abc");//把bu1的地址赋值给了bu2
System.out.println(bu1);//"abc"
System.out.println(bu2);//"abc"
System.out.println(bu1==bu2);//比较的是地址 true


//使用append方法无需接收返回值
bu.append("abc");
bu.append(1);
bu.append(true);
bu.append(8.8);
bu.append('中');
System.out.println(bu);//abc1true8.8中


//链式编程:方法返回值是一个对象,可以继续调用方法
bu.append("abc").append(1).append(true).append(8.8).append('中');
System.out.println(bu);//abc1true8.8中

备注:StringBuilder已经覆盖重写了Object当中的toString方法。

insert方法

public StringBuilder insert(int offset, char c):将 char 参数的字符串表示形式插入此序列中。

public StringBuilder insert(int offset, char[] str):将 char 数组参数的字符串表示形式插入此序列中。

public StringBuilder insert(int offset, String str):将字符串插入此字符序列。

1
2
3
4
5
6
7
8
9
StringBuilder bu1 = new StringBuilder();

bu1.append("abc");

System.out.println(bu1);//"abc"

bu1.insert(0,"cde");

System.out.println(bu1); //cdeabc

delete方法

public StringBuilder delete(int start,int end):移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end -1处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。

1
2
3
4
5
6
7
8
9
StringBuilder bu1 = new StringBuilder();

bu1.append("abcde");

System.out.println(bu1);//abcde

bu1.delete(0,3);

System.out.println(bu1); //de

deleteCharAt方法

public StringBuilder deleteCharAt(int index):移除此序列指定位置上的 char。此序列将缩短一个 char。

1
2
3
4
5
6
7
8
9
StringBuilder bu1 = new StringBuilder();

bu1.append("abcde");

System.out.println(bu1);//abcde

bu1.deleteCharAt(2);

System.out.println(bu1); //abde

substring方法

同String的substring方法,此方法可以返回String

**public String substring(int index)**:截取从参数位置一直到字符串末尾,返回新字符串

**public String substring(int begin, int end)**:截取从begin开始,一直到end结束,中间的字符串。

toString方法

public String toString():将当前StringBuilder对象转换为String对象。

1
2
3
4
5
6
7
8
9
// 链式创建

StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");

// 调用方法

String str = sb.toString();

System.out.println(str); // HelloWorldJava

reverse方法

public StringBuilder reverse():将当前StringBuilder对象反转

1
2
3
4
5
6
7
8
9
StringBuilder bu1 = new StringBuilder();

bu1.append("abc");

System.out.println(bu1);//abc

bu1.reverse();

System.out.println(bu1); //cba

replace方法

public StringBuilder replace(int start,int end,String str):使用给定 String 中的字符替换此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String 插入 start。(如果需要,序列将延长,以适应指定的字符串。)

1
2
3
4
5
6
7
8
9
StringBuilder bu1 = new StringBuilder();

bu1.append("abcde");

System.out.println(bu1);//abcde

bu1.replace(0,3, "kkkkkk");

System.out.println(bu1); //kkkkkkde

StringBuilder
http://example.com/2023/05/13/Java/Java常用类/StringBuilder/
作者
PALE13
发布于
2023年5月13日
许可协议