Java字符串四大类之String、StringBuffer、StringBuilder、StringJoiner详解
作者:End小插曲
前言
在 Java 开发中,字符串操作是高频场景,而 String、StringBuffer、StringBuilder、StringJoiner 这四个类是处理字符串的核心工具。很多开发者在日常使用中容易混淆它们的特性和适用场景,本文将从「核心区别」「构造方法」「常用方法」「实战示例」四个维度全面拆解,帮助大家系统掌握,方便后续复习查阅。
一、核心区别总览(复习核心)
这四个类的核心差异集中在「可变性」「线程安全」和「性能」上,是选择使用场景的关键依据。用表格直观呈现:
| 类名 | 可变性 | 线程安全 | 性能 | 底层实现 | 核心适用场景 |
|---|---|---|---|---|---|
| String | 不可变(final 修饰) | 安全(无修改操作,天然线程安全) | 最低(频繁拼接产生大量临时对象) | JDK8 及之前:char[];JDK9+:byte[](节省内存) | 字符串常量、少量不修改的字符串(如配置项、固定文本) |
| StringBuilder | 可变 | 不安全(无同步锁) | 最高(无锁 overhead) | 可变 char[] 数组 | 单线程环境下频繁拼接/修改字符串(日常开发首选) |
| StringBuffer | 可变 | 安全(方法加 synchronized 锁) | 中等(比 StringBuilder 低 10%-20%) | 可变 char[] 数组 | 多线程环境下频繁拼接/修改字符串(如多线程日志生成) |
| StringJoiner | 可变(封装 StringBuilder) | 不安全(依赖底层 StringBuilder) | 与 StringBuilder 一致 | 内部持有 StringBuilder 对象 | 带分隔符的字符串拼接(如 a,b,c、[x,y,z],无需手动处理分隔符) |
二、逐个拆解:构造方法 + 常用方法
每个类的构造方法和常用方法是实际开发的基础,下面逐个梳理
1. String(不可变字符串)
String 是 Java 最基础的字符串类,一旦创建,内容无法修改。所有“修改”操作(如 substring、replace)都会生成新的 String 对象。
(1)核心构造方法
| 构造方法 | 说明 | 示例 |
|---|---|---|
| String() | 创建空字符串对象 | String str = new String(); |
| String(String original) | 通过已有字符串创建(复用内容) | String str = new String(“hello”); |
| String(char[] value) | 通过字符数组创建 | char[] arr = {‘a’,‘b’,‘c’}; String str = new String(arr); |
| String(byte[] bytes) | 通过字节数组创建(使用默认编码) | byte[] bytes = “abc”.getBytes(); String str = new String(bytes); |
| String(byte[] bytes, String charsetName) | 通过字节数组+指定编码创建 | String str = new String(bytes, “UTF-8”); |
(2)常用方法(必须掌握)
| 方法名 | 说明 | 示例 | 返回结果 |
|---|---|---|---|
| int length() | 获取字符串长度 | “abc”.length() | 3 |
| char charAt(int index) | 获取指定索引的字符(索引从 0 开始) | “abc”.charAt(1) | ‘b’ |
| String substring(int start, int end) | 截取子串(左闭右开,end 不包含) | “abcde”.substring(1,3) | “bc” |
| boolean equals(Object obj) | 比较字符串内容(区分大小写) | “abc”.equals(“ABC”) | false |
| boolean equalsIgnoreCase(String str) | 比较字符串内容(忽略大小写) | “abc”.equalsIgnoreCase(“ABC”) | true |
| int indexOf(String str) | 查找子串首次出现的索引(无则返回 -1) | “abcabc”.indexOf(“bc”) | 1 |
| String replace(CharSequence old, CharSequence new) | 替换字符/字符串 | “abac”.replace(“a”, “x”) | “xbxc” |
| String[] split(String regex) | 按分隔符拆分字符串(regex 支持正则) | “a,b,c”.split(“,”) | [“a”,“b”,“c”] |
| boolean isEmpty() | 判断字符串是否为空(长度为 0) | “”.isEmpty() | true |
2. StringBuilder(可变、单线程首选)
专为单线程场景设计,可变字符序列,所有操作都在同一个对象上完成,无额外内存开销,是日常字符串拼接的最优选择。
(1)核心构造方法
| 构造方法 | 说明 | 示例 |
|---|---|---|
| StringBuilder() | 创建空对象,初始容量 16 | StringBuilder sb = new StringBuilder(); |
| StringBuilder(int capacity) | 指定初始容量(减少扩容开销,推荐) | StringBuilder sb = new StringBuilder(32); |
| StringBuilder(CharSequence seq) | 通过字符串/字符序列初始化 | StringBuilder sb = new StringBuilder(“hello”); |
(2)常用方法(必须掌握)
注:方法均返回自身对象,支持链式调用。
| 方法名 | 说明 | 示例(基于 sb = new StringBuilder(“abc”)) | 操作后 sb 内容 |
|---|---|---|---|
| StringBuilder append(任意类型) | 拼接内容(支持字符串、数字、对象等) | sb.append(123).append(“def”) | “abc123def” |
| String toString() | 转换为最终的 String 对象(必调方法) | sb.toString() | “abc123def” |
| StringBuilder delete(int start, int end) | 删除指定区间字符(左闭右开) | sb.delete(1,3) | “a123def” |
| StringBuilder insert(int offset, 任意类型) | 在指定位置插入内容 | sb.insert(3, “xyz”) | “abcxyz123def” |
| StringBuilder reverse() | 反转字符串 | sb.reverse() | “fed321cba” |
| int capacity() | 获取当前容量(底层数组长度) | sb.capacity() | 初始 16,扩容后按 2*capacity+2 增长 |
| void setLength(int newLength) | 设置字符串长度(短则截断,长则补 ‘\0’) | sb.setLength(5) | “abc12” |
3. StringBuffer(可变、多线程安全)
与 StringBuilder 功能完全一致,唯一区别是所有方法都加了 synchronized 关键字,保证多线程安全,但性能略低。
(1)核心构造方法
与 StringBuilder 完全相同:
// 1. 空构造,初始容量 16
StringBuffer sb = new StringBuffer();
// 2. 指定初始容量
StringBuffer sb = new StringBuffer(64);
// 3. 用字符串初始化
StringBuffer sb = new StringBuffer("hello");
(2)常用方法
与 StringBuilder 完全相同,仅多了线程安全特性。示例(多线程拼接):
StringBuffer sb = new StringBuffer();
// 多线程拼接不会出现数据错乱
new Thread(() -> sb.append("a")).start();
new Thread(() -> sb.append("b")).start();
// 最终 sb 内容为 "ab" 或 "ba",但长度一定是 2(线程安全)
4. StringJoiner(JDK8+,分隔符拼接专用)
JDK8 引入的工具类,本质是对 StringBuilder 的封装,专为「带分隔符的字符串拼接」设计,无需手动处理“最后多一个分隔符”的问题,语法更简洁。
(1)核心构造方法
| 构造方法 | 说明 | 示例 |
|---|---|---|
| StringJoiner(CharSequence delimiter) | 仅指定分隔符 | StringJoiner joiner = new StringJoiner(“,”); |
| StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) | 指定分隔符 + 前缀 + 后缀(常用) | StringJoiner joiner = new StringJoiner(“,”, “[”, “]”); |
(2)常用方法
注:方法返回自身,支持链式调用。
| 方法名 | 说明 | 示例(基于 joiner = new StringJoiner(“,”, “[”, “]”)) | 操作后结果 |
|---|---|---|---|
| StringJoiner add(CharSequence newElement) | 添加拼接元素 | joiner.add(“Java”).add(“Python”).add(“Go”) | “[Java,Python,Go]” |
| String toString() | 转换为最终 String 对象 | joiner.toString() | “[Java,Python,Go]” |
| StringJoiner merge(StringJoiner other) | 合并另一个 StringJoiner(复用分隔符/前缀/后缀) | joiner.merge(new StringJoiner(“,”).add(“C++”)) | “[Java,Python,Go,C++]” |
| StringJoiner setEmptyValue(CharSequence emptyValue) | 设置空值时的默认输出(无元素时生效) | new StringJoiner(“,”).setEmptyValue(“空”).toString() | “空” |
三、实战示例对比(直观理解差异)
用四个类分别实现「拼接 1-10 的数字为 “1,2,3,…,10”」,对比实现复杂度和性能:
import java.util.StringJoiner;
public class StringCompareDemo {
public static void main(String[] args) {
// 1. String(性能差,不推荐频繁拼接)
String str = "";
for (int i = 1; i <= 10; i++) {
str += i + (i == 10 ? "" : ","); // 手动处理分隔符,频繁生成临时对象
}
System.out.println("String: " + str); // 输出:1,2,3,4,5,6,7,8,9,10
// 2. StringBuilder(单线程推荐,高性能)
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++) {
sb.append(i);
if (i != 10) sb.append(","); // 手动处理分隔符
}
System.out.println("StringBuilder: " + sb); // 输出:1,2,3,4,5,6,7,8,9,10
// 3. StringBuffer(多线程用,单线程没必要)
StringBuffer sbf = new StringBuffer();
for (int i = 1; i <= 10; i++) {
sbf.append(i).append(i == 10 ? "" : ",");
}
System.out.println("StringBuffer: " + sbf); // 输出:1,2,3,4,5,6,7,8,9,10
// 4. StringJoiner(分隔符拼接最优,无需手动处理分隔符)
StringJoiner joiner = new StringJoiner(",");
for (int i = 1; i <= 10; i++) {
joiner.add(String.valueOf(i)); // 直接添加,自动处理分隔符
}
System.out.println("StringJoiner: " + joiner); // 输出:1,2,3,4,5,6,7,8,9,10
}
}
四、总结(复习核心原则)
如果字符串无需修改(如常量、配置):用 String;
如果单线程环境下需要频繁拼接/修改:用 StringBuilder(首选);
如果多线程环境下需要频繁拼接/修改:用 StringBuffer;
如果需要拼接带分隔符的字符串(如列表、数组转字符串):用 StringJoiner(JDK8+)
到此这篇关于Java字符串四大类之String、StringBuffer、StringBuilder、StringJoiner的文章就介绍到这了,更多相关Java字符串String、StringBuffer、StringBuilder、StringJoiner内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
