✅ 一、为什么要学 StringBuilder?先搞懂核心痛点
Java 中的 String 字符串是【不可变】的 !
不可变:指一个
String对象一旦创建,它的内容(字符)就永远不能修改。
比如我们写字符串拼接:
java
运行
ini
String str = "a";
str = str + "b";
str = str + "c";
看似是给str追加了内容,实际底层逻辑:
- 先创建
"a"对象 → 拼接"b"时,创建新对象"ab"→ 拼接"c"时,再创建新对象"abc" - 原来的
"a"、"ab"会变成垃圾数据,占用内存 + 降低效率
👉 痛点总结 :如果频繁拼接、修改字符串(比如循环拼接、拼接大量内容),用String会产生大量无用对象,效率极低、浪费内存。
而 StringBuilder 就是为了解决这个问题而生的,它的核心特点是:字符串可变容器,增删改查都在「同一个对象」里操作,无额外内存浪费,效率极高。
✅ 二、StringBuilder 核心概念
1. 本质
StringBuilder 是 Java 提供的一个字符串缓冲区类 ,底层是一个可变的字符数组 ,专门用于高效拼接、修改字符串内容。
- 所有字符串的修改操作,都是直接在这个字符数组上完成,不会创建新对象
- 我们之前手写的
char[]字符数组,其实就是StringBuilder的底层原理,StringBuilder是 Java 帮我们封装好的「好用的字符数组工具类」
2. 核心特点
- 可变的:内容可以随时追加、插入、删除、替换,核心优势!
- 效率极高:所有操作都在一个对象内完成,无内存浪费
- 线程不安全 :单线程编程(咱们平时写的
main方法、普通业务代码)中使用,速度更快 - 无 final 修饰:可以被继承、重写方法(实际开发几乎不用)
✅ 三、StringBuilder 基础用法(必学,固定格式)
✔ 第一步:创建 StringBuilder 对象
两种常用创建方式,都是无参 / 有参构造,任选其一:
java
运行
ini
// 方式1:无参构造(推荐),创建一个空的字符串缓冲区,初始容量默认16个字符
StringBuilder sb = new StringBuilder();
// 方式2:有参构造,创建时直接放入初始字符串
StringBuilder sb = new StringBuilder("初始内容");
✔ 第二步:核心操作(拼接 / 修改字符串)
StringBuilder 提供了一系列方法来操作字符串,所有方法调用后,都是直接修改自身对象,不需要接收返回值 ,这是和String最大的区别!
✨ 重点必学的 5 个核心方法(覆盖 99% 的开发场景)
所有方法我都给了代码示例,直接复制就能运行,建议跟着敲一遍!
java
运行
go
public class StringBuilderDemo {
public static void main(String[] args) {
// 1. 创建对象
StringBuilder sb = new StringBuilder();
// ========== 方法1:append(任意类型) 追加内容【最常用】 ==========
// 可以追加:字符串、字符、数字、布尔值、数组...所有类型都支持
sb.append("姓名:");
sb.append("张三");
sb.append(",年龄:");
sb.append(20);
sb.append(",是否有驾照:");
sb.append(true);
// 此时sb的内容:姓名:张三,年龄:20,是否有驾照:true
// ========== 方法2:toString() 转换为String类型【必须会】 ==========
// 注意:StringBuilder不是String类型,无法直接赋值给String变量
// 所有操作完成后,用toString()转为String,才能正常使用字符串
String result = sb.toString();
System.out.println(result); // 输出:姓名:张三,年龄:20,是否有驾照:true
// ========== 方法3:insert(索引, 内容) 插入内容 ==========
// 在指定索引位置插入内容,原位置的字符会向后移
sb.insert(4, "(司机)");
System.out.println(sb); // 输出:姓名:张三(司机),年龄:20,是否有驾照:true
// ========== 方法4:delete(起始索引, 结束索引) 删除内容 ==========
// 左闭右开:包含起始索引,不包含结束索引
sb.delete(4,8); // 删除 (司机) 这几个字
System.out.println(sb); // 输出:姓名:张三,年龄:20,是否有驾照:true
// ========== 方法5:reverse() 反转字符串 ==========
sb.reverse();
System.out.println(sb); // 输出:eurT:照驾有否是,02:龄年,三张:名姓
}
}
✔ 补充 3 个常用小方法(锦上添花)
java
运行
scss
StringBuilder sb = new StringBuilder("Java学习");
sb.replace(0,4,"Python"); // 替换:索引0-4的内容换成Python → 结果:Python学习
sb.length(); // 获取长度 → 6
sb.charAt(2); // 获取指定索引的字符 → t
✅ 四、StringBuilder vs String 核心对比(必考 + 必懂)
这是 Java 基础面试高频题,也是咱们写代码的核心选择依据,一张表讲清所有区别,建议牢记:
| 特性 | String 字符串 |
StringBuilder 字符串缓冲区 |
|---|---|---|
| 可变性 | ✅ 不可变(内容不能改) | ✅ 可变(内容随便改) |
| 内存效率 | ❌ 低,拼接创建新对象 | ✅ 极高,修改不创建新对象 |
| 拼接方式 | 用 + 号拼接 |
用 append() 方法拼接 |
| 核心场景 | 字符串内容固定不变时使用(比如定义常量、少量拼接) | 字符串需要频繁拼接 / 修改时使用(比如循环拼接、动态拼接内容) |
| 转换关系 | String → StringBuilder:new StringBuilder(str) |
StringBuilder → String:sb.toString() |
✅ 经典对比案例(你的代码能用到)
比如拼接 1-100 的数字,两种方式的效率天差地别:
java
运行
ini
// 1. String拼接 → 效率极低,创建大量垃圾对象
String str = "";
for (int i = 1; i <= 100; i++) {
str += i;
}
// 2. StringBuilder拼接 → 效率极高,仅一个对象
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 100; i++) {
sb.append(i);
}
String result = sb.toString();
✅ 五、StringBuilder 实战案例(贴合你的代码场景)
结合你之前写的【汽车司机类】【数值比较类】,给你 2 个你能直接用到作业里的实战案例,学完就会用!
案例 1:拼接司机信息(替换你之前的 toString 方法)
你之前写的CarDriver类里,toString 方法是手动拼接字符串,用StringBuilder更高效,推荐这么写:
java
运行
scss
// 司机类的toString方法优化(推荐写法)
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("汽车司机信息:");
sb.append("\n姓名:").append(name);
sb.append("\n性别:").append(gender);
sb.append("\n年龄:").append(age);
sb.append("\n驾驶证号:").append(license);
sb.append("\n车牌号:").append(number);
return sb.toString();
}
案例 2:拼接数组内容(你之前写的数值比较类里的数组)
你之前写了double[] arr = {a,b,c},用StringBuilder可以快速把数组内容拼接成字符串打印,非常实用:
java
运行
ini
public void compare(double a, double b, double c) {
double [] arr = {a,b,c};
// 用StringBuilder拼接数组内容
StringBuilder sb = new StringBuilder("比较的三个数:");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]).append(" ");
}
System.out.println(sb); // 输出:比较的三个数:0.1 0.1 0.1
double temp = arr[0];
for (int i = 1; i < arr.length; i++) {
if (temp < arr[i]) {
temp = arr[i];
}
}
System.out.println("最大值为:"+temp);
}
✅ 六、拓展补充:StringBuilder 和 StringBuffer
这两个类用法完全一样,99% 的方法都是同名的,唯一区别:
StringBuilder:线程不安全,效率更高 → 单线程用它(咱们所有作业 / 练习都用这个)StringBuffer:线程安全,效率稍低 → 多线程开发时使用(暂时不用学)
一句话总结:日常写代码,无脑用
StringBuilder就对了!
✅ 七、所有知识点总结(精华版,必背)
String不可变,拼接多了效率低;StringBuilder可变,专门解决字符串频繁修改 / 拼接的问题。StringBuilder底层是可变字符数组,所有操作都在自身对象完成,无内存浪费。- 核心三步:创建对象 → append () 拼接 → toString () 转 String。
- 核心方法:
append()(追加)、toString()(转换)、insert()(插入)、delete()(删除)、reverse()(反转)。 - 使用场景:只要你需要拼接字符串、修改字符串内容 ,就用
StringBuilder;字符串固定不变,就用String。
✅ 附赠:你之前报错的 Math 类代码 + StringBuilder 优化版
把你之前的代码整合优化,加入 StringBuilder,直接复制可用:
java
运行
csharp
// com.shehuiuniversity.MyMath.java
package com.shehuiuniversity;
public class MyMath {
public void add(int a, int b) {
int add = a + b;
System.out.println(a + " + " + b + " = " + add);
}
public void compare(double a, double b,double c) {
double [] arr = {a,b,c};
StringBuilder sb = new StringBuilder();
sb.append("参与比较的数值:").append(a).append(",").append(b).append(",").append(c);
System.out.println(sb);
double temp = arr[0];
for (int i = 1; i < arr.length; i++) {
if (temp < arr[i]) {
temp = arr[i];
}
}
System.out.println("最大值为:"+temp);
}
}
// com.Testclass.MathTest.java
package com.Testclass;
import com.shehuiuniversity.MyMath;
public class MathTest {
public static void main(String[] args) {
MyMath ma = new MyMath();
ma.compare(0.1,0.5,0.3); // 正确调用,无报错
ma.add(10,20);
}
}
运行结果:
plaintext
ini
参与比较的数值:0.1,0.5,0.3
最大值为:0.5
10 + 20 = 30