1. StringBuilder 概述
1.1 什么是 StringBuilder
与 String 相似,StringBuilder 也是一个与字符串相关的类
Java 官方文档给 StringBuilder 的定义是:可变的字符序列。
1.2 为什么需要 StringBuilder
在 Java 字符串的学习中,我们知道了字符串具有不可变性,当频繁操作字符串时候,会在常量池中产生很多无用的数据
而 StringBuilder 与 String 不同,它具有可变性。相较 String 类不会产生大量无用数据,性能上会大大提高。
因此对于需要频繁操作字符串的场景,建议使用 Stringbuilder 类来代替 String 类。
2. StringBuffer 概述
2.1 定义
了解了 StringBuilder 类 ,StringBuffer 也是不得不提的一个类,Java 官方文档给出的定义是:线程安全的可变字符序列。
2.2 与前者的区别
StringBuffer 是 StringBuilder 的前身,在早期的 Java 版本中应用非常广泛,它是 StringBuilder 的线程安全版本(线程我们将在后面的小节中介绍),但实现线程安全的代价是执行效率的下降。
你可以对比 StringBuilder 和 StringBuffer 的接口文档,它们的接口基本上完全一致。为了提升我们代码的执行效率,在如今的实际开发中 StringBuffer 并不常用。
3. StringBuilder 的常用方法
3.1 构造方法
StringBuilder 类提供了如下 4 个构造方法:
StringBuilder() 构造一个空字符串生成器,初始容量为 16 个字符;
StringBuilder(int catpacity) 构造一个空字符串生成器,初始容量由参数 capacity 指定;
StringBuilder(CharSequence seq) 构造一个字符串生成器,该生成器包含与指定的 CharSequence 相同的字符。;
StringBuilder(String str) 构造初始化为指定字符串内容的字符串生成器。
其中第 4 个构造方法最为常用,我们可以使用 StringBuilder 这样初始化一个内容为 hello 的字符串:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("8/24"); } }
3.2 成员方法
StringBuilder 类下面也提供了很多与 String 类相似的成员方法,以方便我们对字符串进行操作。下面我们将举例介绍一些常用的成员方法。
3.2.1 字符串连接
可以使用 StringBuilder 的 StringBuilder append(String str) 方法来实现字符串的连接操作。
我们知道,String 的连接操作是通过 + 操作符完成连接的:
String str1 = "Hello"; String str2 = "World"; String str3 = str1 + " " + str2;
如下是通过 StringBuilder 实现的字符串连接示例:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("8/24"); str.append(" "); str.append("world"); System.out.println(str); } }
运行结果:
8/24 world
由于 append() 方法返回的是一个 StringBuilder 类型,我们可以实现链式调用。例如,上述连续两个 append() 方法的调用语句,可以简化为一行语句:
//链式调用 str.append(" ").append("world"); 如果你使用 IDE 编写如上连接字符串的代码,可能会有下面这样的提示(IntelliJ idea 的代码截图):
提示内容说可以将 StringBuilder 类型可以替换为 String 类型,也就是说可以将上边地代码改为:
String str = "8/24" + " " + "world";
这样写并不会导致执行效率的下降,这是因为 Java 编译器在编译和运行期间会自动将字符串连接操作转换为 StringBuilder 操作或者数组复制,间接地优化了由于 String 的不可变性引发的性能问题。
值得注意的是,append() 的重载方法有很多,可以实现各种类型的连接操作。例如我们可以连接 char 类型以及 float 类型,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { StringBuilder str = new StringBuilder("zs的身高是"); str.append(':').append(172.5f); System.out.println(str); } }
运行结果:
zs的身高是:172.5
上面代码里连续的两个 append() 方法分别调用的是重载方法 StringBuilder append(char c) 和 StringBuilder append(float f)。
3.2.2 获取容量
可以使用 int capacity() 方法来获取当前容量,容量指定是可以存储的字符数(包含已写入字符),超过此数将进行自动分配。注意,容量与长度(length)不同,长度指的是已经写入字符的长度。
例如,构造方法 StringBuilder() 构造一个空字符串生成器,初始容量为 16 个字符。我们可以获取并打印它的容量,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder(); System.out.println(stringBuilder.capacity()); for (int i = 0; i < 17; i++) { stringBuilder.append(i); } System.out.println(stringBuilder.capacity()); } }
运行结果:
16
34
3.2.3 字符串替换
可以使用 StringBuilder replace(int start, int end, String str) 方法,来用指定字符串替换从索引位置 start 开始到 end 索引位置结束(不包含 end)的子串。实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); // 调用字符串替换方法,将 monkey 替换为 Jack stringBuilder.replace(6,12, "Jack"); System.out.println(stringBuilder); } }
在IDEA里,是有提示的
运行结果:
Hello Jack
也可使用 StringBuilder delete(int start, int end) 方法,先来删除索引位置 start 开始到 end 索引位置(不包含 end)的子串,再使用 StringBuilder insert(int offset, String str) 方法,将字符串插入到序列的 offset 索引位置。同样可以实现字符串的替换,例如:
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); stringBuilder.delete(6,12); //从第6位开始插入,内容是Jack stringBuilder.insert(6,"Jack"); System.out.println(stringBuilder); } }
3.2.4 字符串截取
可以使用 StringBuilder substring(int start) 方法来进行字符串截取,例如,我们想截取字符串的第7到第9个字符,实例如下:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); String str = stringBuilder.substring(7, 9); System.out.println(str); } }
运行结果:
on
3.2.5 字符串反转
可以使用 StringBuildr reverse() 方法,对字符串进行反转操作,例如:
实例演示
package com.caq.oop.demo08; public class Test { public static void main(String[] args) { // 调用StringBuilder的无参构造方法,生成一个str对象 StringBuilder stringBuilder = new StringBuilder("Hello monkey"); System.out.println(stringBuilder.reverse()); } }
运行结果:
yeknom olleH
4. 小结
今天我们介绍了 Java 的 StringBuilder 类,它具有可变性,对于频繁操作字符串的场景,使用它来代替 String 类可以提高程序的执行效率;