StringBuilder 概述
与 String 的对比
| 特性 | String | StringBuilder |
|---|---|---|
| 可变性 | 不可变(immutable) | 可变(mutable) |
| 线程安全 | 线程安全 | 线程不安全 |
| 性能 | 频繁修改时性能差 | 频繁修改时性能好 |
| 内存 | 每次修改都创建新对象 | 在原有对象上修改 |
| 适用场景 | 字符串不经常修改 | 字符串频繁修改 |
为什么需要 StringBuilder
-
String 的缺点:每次修改都会创建新对象,效率低下
-
StringBuilder 的优点:内部维护可变字符数组,修改时直接在原数组上操作
构造方法
1. 创建空白 StringBuilder
java
// 语法:StringBuilder sb = new StringBuilder();
// 功能:创建一个初始容量为16的空StringBuilder
StringBuilder sb1 = new StringBuilder();
System.out.println(sb1.toString()); // 输出空字符串:""
System.out.println(sb1.length()); // 输出:0
System.out.println(sb1.capacity()); // 输出:16(默认容量)
2. 根据字符串创建 StringBuilder
java
// 语法:StringBuilder sb = new StringBuilder(String str);
// 功能:创建一个包含指定字符串的StringBuilder,容量为 str.length() + 16
StringBuilder sb2 = new StringBuilder("Hello");
System.out.println(sb2.toString()); // 输出:"Hello"
System.out.println(sb2.length()); // 输出:5
System.out.println(sb2.capacity()); // 输出:21(5 + 16)
3. 指定初始容量
java
// 语法:StringBuilder sb = new StringBuilder(int capacity);
// 功能:创建一个指定初始容量的StringBuilder
StringBuilder sb3 = new StringBuilder(100);
System.out.println(sb3.length()); // 输出:0
System.out.println(sb3.capacity()); // 输出:100
常用方法详解
1. append() 方法
java
// 语法:StringBuilder append(任意类型)
// 功能:添加数据到末尾,返回对象本身(支持链式调用)
// 参数:支持所有基本类型和对象类型
StringBuilder sb = new StringBuilder();
// 追加字符串
sb.append("Hello");
sb.append(" ");
sb.append("World");
System.out.println(sb.toString()); // "Hello World"
// 追加基本类型
sb.append(123); // 追加整数
sb.append(3.14); // 追加小数
sb.append(true); // 追加布尔值
sb.append('!'); // 追加字符
// 追加对象(会自动调用toString())
sb.append(new Person("张三", 20));
System.out.println(sb.toString()); // "Hello World1233.14true!Person{name='张三', age=20}"
2. reverse() 方法
java
// 语法:StringBuilder reverse()
// 功能:反转字符串内容,返回对象本身
StringBuilder sb = new StringBuilder("Hello World");
sb.reverse();
System.out.println(sb.toString()); // "dlroW olleH"
// 链式调用
String reversed = new StringBuilder("Java").reverse().toString();
System.out.println(reversed); // "avaJ"
3. length() 方法
java
// 语法:int length()
// 功能:返回当前字符串的长度
StringBuilder sb = new StringBuilder("Hello");
System.out.println(sb.length()); // 5
sb.append(" World");
System.out.println(sb.length()); // 11
4. toString() 方法
java
// 语法:String toString()
// 功能:将StringBuilder转换为不可变的String对象
StringBuilder sb = new StringBuilder("Hello");
String str = sb.toString(); // 转换为String
System.out.println(str); // "Hello"
// 注意:转换后两者独立
sb.append(" World");
System.out.println(sb.toString()); // "Hello World"
System.out.println(str); // "Hello"(str不变)
5. 其他常用方法
insert() 方法
java
// 语法:StringBuilder insert(int offset, 任意类型)
// 功能:在指定位置插入数据
StringBuilder sb = new StringBuilder("HelloWorld");
sb.insert(5, " "); // 在索引5处插入空格
System.out.println(sb); // "Hello World"
sb.insert(6, "Beautiful "); // 在索引6处插入字符串
System.out.println(sb); // "Hello Beautiful World"
delete() 方法
java
// 语法:StringBuilder delete(int start, int end)
// 功能:删除[start, end)范围内的字符
StringBuilder sb = new StringBuilder("Hello World");
sb.delete(5, 11); // 删除索引5到10的字符
System.out.println(sb); // "Hello"
sb.deleteCharAt(4); // 删除索引4的字符
System.out.println(sb); // "Hell"
replace() 方法
java
// 语法:StringBuilder replace(int start, int end, String str)
// 功能:替换指定范围的字符
StringBuilder sb = new StringBuilder("Hello World");
sb.replace(6, 11, "Java"); // 将"World"替换为"Java"
System.out.println(sb); // "Hello Java"
capacity() 方法
java
// 语法:int capacity()
// 功能:返回当前容量(不是长度)
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity()); // 16
sb.append("This is a very long string that will exceed initial capacity");
System.out.println(sb.length()); // 实际长度
System.out.println(sb.capacity()); // 自动扩容后的容量
链式编程
概念
-
定义:在一个语句中连续调用多个方法
-
前提 :方法返回对象本身(通常是
return this;) -
优点:代码简洁,可读性好
示例
java
// 传统写法
StringBuilder sb1 = new StringBuilder();
sb1.append("Hello");
sb1.append(" ");
sb1.append("World");
String result1 = sb1.toString();
// 链式编程写法
String result2 = new StringBuilder()
.append("Hello")
.append(" ")
.append("World")
.toString();
// 更复杂的链式调用
String result3 = new StringBuilder()
.append("姓名:")
.append("张三")
.append(",年龄:")
.append(20)
.append(",成绩:")
.append(95.5)
.reverse() // 反转
.insert(0, "信息:") // 在最前面插入
.toString();
System.out.println(result3);
实际应用示例
示例1:字符串拼接(代替String的+操作)
java
public class StringConcatenation {
public static void main(String[] args) {
// 错误做法:使用String拼接大量字符串
String result1 = "";
for (int i = 0; i < 10000; i++) {
result1 += i; // 每次循环都创建新String对象
}
// 正确做法:使用StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i);
}
String result2 = sb.toString();
// 性能对比
long start = System.currentTimeMillis();
// ... 执行上面的循环
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}
}
示例2:构建SQL语句
java
public class SQLBuilder {
public static String buildSelectSQL(String table, String[] columns, String whereClause) {
StringBuilder sql = new StringBuilder("SELECT ");
// 拼接列名
if (columns == null || columns.length == 0) {
sql.append("*");
} else {
for (int i = 0; i < columns.length; i++) {
sql.append(columns[i]);
if (i < columns.length - 1) {
sql.append(", ");
}
}
}
// 拼接表名
sql.append(" FROM ").append(table);
// 拼接WHERE条件
if (whereClause != null && !whereClause.trim().isEmpty()) {
sql.append(" WHERE ").append(whereClause);
}
// 添加分号
sql.append(";");
return sql.toString();
}
public static void main(String[] args) {
String[] columns = {"id", "name", "age"};
String sql = buildSelectSQL("users", columns, "age > 18");
System.out.println(sql);
// 输出:SELECT id, name, age FROM users WHERE age > 18;
}
}
示例3:格式化输出
java
public class FormattedOutput {
public static void main(String[] args) {
// 构建表格输出
StringBuilder table = new StringBuilder();
// 表头
table.append("+------------+------------+------------+\n")
.append("| 姓名 | 年龄 | 成绩 |\n")
.append("+------------+------------+------------+\n");
// 数据行
String[][] data = {
{"张三", "20", "85"},
{"李四", "22", "92"},
{"王五", "21", "78"}
};
for (String[] row : data) {
table.append(String.format("| %-10s | %-10s | %-10s |\n", row[0], row[1], row[2]));
}
// 表尾
table.append("+------------+------------+------------+\n");
System.out.println(table.toString());
}
}
示例4:字符串处理工具
java
public class StringUtils {
// 反转字符串
public static String reverse(String str) {
if (str == null) return null;
return new StringBuilder(str).reverse().toString();
}
// 判断是否为回文
public static boolean isPalindrome(String str) {
if (str == null) return false;
String reversed = new StringBuilder(str).reverse().toString();
return str.equals(reversed);
}
// 重复字符串n次
public static String repeat(String str, int n) {
if (str == null || n <= 0) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(str);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(reverse("Hello")); // olleH
System.out.println(isPalindrome("racecar")); // true
System.out.println(isPalindrome("hello")); // false
System.out.println(repeat("Java", 3)); // JavaJavaJava
}
}
注意事项
1. 线程安全性
java
// StringBuilder:线程不安全(但性能好)
// StringBuffer:线程安全(但性能稍差)
// 单线程环境:使用StringBuilder(推荐)
StringBuilder sb1 = new StringBuilder();
// 多线程环境:使用StringBuffer
StringBuffer sb2 = new StringBuffer();
2. 性能优化
java
// 如果知道大致长度,可以预先设置容量
StringBuilder sb = new StringBuilder(1000); // 避免频繁扩容
// 链式调用时,toString()在最后调用一次即可
String result = new StringBuilder()
.append("a").append("b").append("c")
.toString(); // 只转换一次
3. 与String的互操作
java
// String -> StringBuilder
String str = "Hello";
StringBuilder sb = new StringBuilder(str);
// StringBuilder -> String
String result = sb.toString();
// 注意:转换后两者独立
sb.append(" World");
System.out.println(sb); // "Hello World"
System.out.println(str); // "Hello"
StringBuilder 是处理可变字符串的高效工具,特别适合需要频繁修改字符串的场景。掌握它的使用可以显著提高程序性能。
java
public class StringBuilderDemo1 {
public static void main(String[] args) {
//1.创建对象
StringBuilder sb = new StringBuilder("HelloWorld");
//添加元素
sb.append(1);
sb.append(2.3);
sb.append(true);
//反转
sb.reverse();
//获取长度
int len = sb.length();
//变回字符串
String str = sb.toString();
//打印
System.out.println(sb);
System.out.println(len);
System.out.println(str);
}
}
java
import java.util.Scanner;
public class StringBuilderDemo2 {
public static void main(String[] args) {
//键盘录入一个字符串
Scanner Sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = Sc.next();
//反转键盘录入的字符串
String result = new StringBuilder().append(str).reverse().toString();
//比较
if (str.equals(result)){
System.out.println("是对称字符串");
}else {
System.out.println("不是对称字符串");
}
}
}
java
public class StringBuilderDemo3 {
public static void main(String[] args) {
int[] arr = {1,2,3};
String str = arrToString(arr);
System.out.println(str);
}
public static String arrToString(int[] arr) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]).append("]");
} else {
sb.append(arr[i]).append(",");
}
}
return sb.toString();
}
}