文章目录

Java 字符串操作:String 与 StringBuilder

发布于 2026-04-03 13:30:07 · 浏览 5 次 · 评论 0 条

Java 字符串操作:String 与 StringBuilder

在 Java 中处理文本时,你会频繁使用字符串。但 Java 提供了两种主要方式:StringStringBuilder。它们看似都能存文字,实际性能和用途差别很大。选错类型可能导致程序变慢甚至卡顿。下面直接告诉你怎么选、怎么用。


理解 String 的“不可变”特性

创建一个 String 对象后,它的内容就再也改不了。这不是限制,而是设计原则。

String name = "张三";
name = name + "同学"; // 表面上看是“修改”,其实是新建

上面这行代码实际做了三件事:

  1. 创建原始字符串 "张三"
  2. 创建新字符串 "同学"
  3. 拼接两者,生成第三个全新字符串 "张三同学",然后让变量 name 指向它。

旧的 "张三" 并未被修改,只是不再被引用,等着被垃圾回收。每次“修改”都意味着新建对象、分配内存、复制字符——频繁操作会严重拖慢程序。

适用场景:字符串内容确定不变,或只做少量拼接(比如拼一两次日志)。


使用 StringBuilder 高效拼接

当你需要反复修改字符串内容(比如循环中拼接),必须用 StringBuilder

创建一个 StringBuilder 实例:

StringBuilder sb = new StringBuilder();

它内部维护一个可变的字符数组。所有“修改”操作都在这个数组上原地进行,避免重复创建对象。

常用操作步骤

  1. 调用 append() 方法追加内容:

    sb.append("今天");
    sb.append("天气");
    sb.append("很好");
  2. 调用 toString() 获取最终结果:

    String result = sb.toString(); // 得到 "今天天气很好"
  3. 清空内容以便复用(可选):

    sb.setLength(0); // 清空,但保留底层数组容量

循环中拼接示例

假设你要把数字 1 到 100 拼成一个字符串:

StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 100; i++) {
    sb.append(i).append(", ");
}
String numbers = sb.toString();

如果用 String 做同样操作,会创建约 100 个中间字符串对象,而 StringBuilder 只用一个底层数组,效率高出几十倍。


性能对比关键点

虽然不需要图表也能说清,但为直观展示差异,列出核心区别:

特性 String StringBuilder
可变性 不可变 可变
线程安全 是(因不可变)
拼接性能(多次) 极差 优秀
内存开销 高(每次新建) 低(原地修改)
适用场景 少量拼接、常量 大量拼接、动态构建

注意:如果你在多线程环境需要可变且线程安全的字符串,应使用 StringBuffer(它是 StringBuilder 的线程安全版本),但绝大多数单线程场景下 StringBuilder 更快。


如何选择?记住这两条规则

  1. 如果字符串只拼接一次或两次(比如组合用户姓名和ID),直接用 String + + 操作符。Java 编译器会自动优化成 StringBuilder,你不用操心。

  2. 如果在循环里、递归中,或不确定拼接次数立即使用 StringBuilder。这是避免性能陷阱的最简单方法。

例如,以下写法是危险的:

String result = "";
for (String item : list) {
    result += item; // 每次循环都新建 String!
}

正确做法:

StringBuilder sb = new StringBuilder();
for (String item : list) {
    sb.append(item);
}
String result = sb.toString();

初始化容量提升效率(进阶技巧)

StringBuilder 默认初始容量是 16 个字符。如果拼接内容远超此数,它会自动扩容(通常是翻倍),但扩容涉及数组复制,仍有开销。

预估长度后指定初始容量,可避免中途扩容:

// 预计最终字符串约 1000 字符
StringBuilder sb = new StringBuilder(1000);

这一步不是必须,但在处理大文本(如生成 HTML、JSON)时能进一步提升性能。


最后提醒:别混淆 equals 和 ==

无论是 String 还是 StringBuilder,比较内容是否相等时,永远不要用 ==

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b);        // false(地址不同)
System.out.println(a.equals(b));   // true(内容相同)

StringBuilder sb1 = new StringBuilder("hello");
StringBuilder sb2 = new StringBuilder("hello");
System.out.println(sb1.equals(sb2)); // false!StringBuilder 没重写 equals

要比较两个 StringBuilder 的内容,先转成 String 再比:

sb1.toString().equals(sb2.toString()); // 正确

创建字符串时,问自己一句:“我会频繁改它吗?”
→ 用 StringBuilder
不会 → 用 String
就这么简单。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文