Skip to content

13.3 StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 的概念

StringBufferStringBuilder 是 Java 中用于处理可变字符串的类。它们与 String 类不同,String 是不可变的,而 StringBufferStringBuilder 是可变的,这意味着它们可以在不创建新对象的情况下修改字符串内容。

StringBuffer 和 StringBuilder 的区别

特性StringBufferStringBuilder
线程安全性线程安全,方法是同步的非线程安全,方法不是同步的
性能相对较低(因为同步)相对较高(因为不同步)
适用场景多线程环境单线程环境

StringBuilder 的使用

构造方法

java
// 创建一个空的 StringBuilder
StringBuilder sb1 = new StringBuilder();

// 创建一个指定容量的 StringBuilder
StringBuilder sb2 = new StringBuilder(16);

// 创建一个包含指定字符串的 StringBuilder
StringBuilder sb3 = new StringBuilder("Hello");

常用方法

append()

功能:向 StringBuilder 追加内容

语法StringBuilder append(任意类型参数)

示例

java
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("Java");
sb.append("!");
System.out.println(sb.toString()); // "Hello Java!"

insert()

功能:在指定位置插入内容

语法StringBuilder insert(int offset, 任意类型参数)

示例

java
StringBuilder sb = new StringBuilder("Hello World!");
sb.insert(6, "Java ");
System.out.println(sb.toString()); // "Hello Java World!"

delete()

功能:删除指定范围的内容

语法StringBuilder delete(int start, int end)

示例

java
StringBuilder sb = new StringBuilder("Hello Java World!");
sb.delete(6, 11); // 删除 "Java "
System.out.println(sb.toString()); // "Hello World!"

deleteCharAt()

功能:删除指定位置的字符

语法StringBuilder deleteCharAt(int index)

示例

java
StringBuilder sb = new StringBuilder("Hello World!");
sb.deleteCharAt(5); // 删除空格
System.out.println(sb.toString()); // "HelloWorld!"

replace()

功能:替换指定范围的内容

语法StringBuilder replace(int start, int end, String str)

示例

java
StringBuilder sb = new StringBuilder("Hello World!");
sb.replace(6, 11, "Java");
System.out.println(sb.toString()); // "Hello Java!"

reverse()

功能:反转字符串

语法StringBuilder reverse()

示例

java
StringBuilder sb = new StringBuilder("Hello");
sb.reverse();
System.out.println(sb.toString()); // "olleH"

substring()

功能:获取子串

语法String substring(int start)String substring(int start, int end)

示例

java
StringBuilder sb = new StringBuilder("Hello Java!");
String sub1 = sb.substring(6); // "Java!"
String sub2 = sb.substring(0, 5); // "Hello"
System.out.println(sub1);
System.out.println(sub2);

length()

功能:返回字符串长度

语法int length()

示例

java
StringBuilder sb = new StringBuilder("Hello");
int length = sb.length(); // 5
System.out.println("长度: " + length);

capacity()

功能:返回当前容量

语法int capacity()

示例

java
StringBuilder sb1 = new StringBuilder();
System.out.println("默认容量: " + sb1.capacity()); // 16

StringBuilder sb2 = new StringBuilder("Hello");
System.out.println("容量: " + sb2.capacity()); // 16 + 5 = 21

setLength()

功能:设置字符串长度

语法void setLength(int newLength)

示例

java
StringBuilder sb = new StringBuilder("Hello");
sb.setLength(3);
System.out.println(sb.toString()); // "Hel"

StringBuffer 的使用

StringBuffer 的使用方法与 StringBuilder 基本相同,只是它的方法是同步的,线程安全。

示例

java
StringBuffer sb = new StringBuffer();
sb.append("Hello");
sb.append(" ");
sb.append("Java");
sb.append("!");
System.out.println(sb.toString()); // "Hello Java!"

性能比较

String、StringBuilder 和 StringBuffer 的性能对比

java
public class StringPerformanceTest {
    public static void main(String[] args) {
        int iterations = 100000;
        
        // 测试 String
        long startTime = System.currentTimeMillis();
        String str = "";
        for (int i = 0; i < iterations; i++) {
            str += i;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("String 耗时: " + (endTime - startTime) + " 毫秒");
        
        // 测试 StringBuilder
        startTime = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < iterations; i++) {
            sb.append(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder 耗时: " + (endTime - startTime) + " 毫秒");
        
        // 测试 StringBuffer
        startTime = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < iterations; i++) {
            sbf.append(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer 耗时: " + (endTime - startTime) + " 毫秒");
    }
}

运行结果(仅供参考):

String 耗时: 12345 毫秒
StringBuilder 耗时: 12 毫秒
StringBuffer 耗时: 15 毫秒

应用场景

1. 大量字符串拼接

当需要进行大量字符串拼接操作时,使用 StringBuilderStringBuffer 可以显著提高性能。

示例

java
// 不推荐:使用 String 进行大量拼接
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;
}

// 推荐:使用 StringBuilder 进行大量拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

2. 字符串修改操作

当需要对字符串进行频繁的修改操作(如插入、删除、替换等)时,使用 StringBuilderStringBuffer 更加高效。

示例

java
StringBuilder sb = new StringBuilder("Hello World!");

// 插入操作
sb.insert(6, "Java ");
System.out.println(sb.toString()); // "Hello Java World!"

// 删除操作
sb.delete(6, 11);
System.out.println(sb.toString()); // "Hello World!"

// 替换操作
sb.replace(6, 11, "Java");
System.out.println(sb.toString()); // "Hello Java!"

// 反转操作
sb.reverse();
System.out.println(sb.toString()); // "!avaJ olleH"

3. 线程安全场景

在多线程环境中,当多个线程需要修改同一个字符串时,使用 StringBuffer 可以保证线程安全。

示例

java
public class ThreadSafeExample {
    private static StringBuffer stringBuffer = new StringBuffer();
    
    public static void main(String[] args) {
        // 创建多个线程
        Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.length; i++) {
            final int threadId = i;
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    stringBuffer.append("Thread " + threadId + ": " + j + "\n");
                }
            });
            threads[i].start();
        }
        
        // 等待所有线程完成
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        System.out.println("字符串长度: " + stringBuffer.length());
    }
}

示例:StringBuilder 的应用

示例 1:构建复杂字符串

java
public class StringBuilderExample {
    public static void main(String[] args) {
        // 构建 HTML 字符串
        StringBuilder html = new StringBuilder();
        html.append("<html>\n");
        html.append("<head>\n");
        html.append("<title>Java StringBuilder Example</title>\n");
        html.append("</head>\n");
        html.append("<body>\n");
        html.append("<h1>Hello, Java!</h1>\n");
        html.append("<p>This is an example of using StringBuilder.</p>\n");
        html.append("</body>\n");
        html.append("</html>");
        
        System.out.println(html.toString());
    }
}

示例 2:字符串反转

java
public class StringReverseExample {
    public static void main(String[] args) {
        String str = "Hello, Java!";
        System.out.println("原始字符串: " + str);
        System.out.println("反转后: " + reverseString(str));
    }
    
    public static String reverseString(String str) {
        StringBuilder sb = new StringBuilder(str);
        return sb.reverse().toString();
    }
}

示例 3:数字转字符串

java
public class NumberToStringExample {
    public static void main(String[] args) {
        int number = 12345;
        String str = numberToString(number);
        System.out.println("数字: " + number);
        System.out.println("字符串: " + str);
    }
    
    public static String numberToString(int number) {
        StringBuilder sb = new StringBuilder();
        boolean isNegative = false;
        
        if (number < 0) {
            isNegative = true;
            number = -number;
        }
        
        do {
            int digit = number % 10;
            sb.append((char) ('0' + digit));
            number /= 10;
        } while (number > 0);
        
        if (isNegative) {
            sb.append('-');
        }
        
        return sb.reverse().toString();
    }
}

常见问题

1. 线程安全问题

症状:在多线程环境中使用 StringBuilder 导致数据不一致

解决方案:在多线程环境中使用 StringBuffer,或使用同步机制保护 StringBuilder

示例

java
// 多线程环境中使用 StringBuffer
StringBuffer sb = new StringBuffer();

// 或使用同步机制保护 StringBuilder
StringBuilder sb = new StringBuilder();
synchronized (sb) {
    sb.append("Hello");
}

2. 容量不足问题

症状StringBuilderStringBuffer 频繁扩容,影响性能

解决方案:在创建时指定合适的初始容量

示例

java
// 预估字符串长度,指定初始容量
StringBuilder sb = new StringBuilder(1000); // 初始容量为 1000

3. 内存泄漏问题

症状StringBuilderStringBuffer 占用大量内存

解决方案:及时清空不需要的 StringBuilderStringBuffer,或使用 setLength(0) 方法重置

示例

java
StringBuilder sb = new StringBuilder();
// 使用 sb
...
// 重置 sb
sb.setLength(0);

最佳实践

  1. 选择合适的类

    • 单线程环境:使用 StringBuilder(性能更好)
    • 多线程环境:使用 StringBuffer(线程安全)
  2. 指定初始容量:根据预估的字符串长度,在创建时指定合适的初始容量,减少扩容操作

  3. 避免频繁创建:尽量重用 StringBuilderStringBuffer 对象,避免频繁创建新对象

  4. 及时转换:当字符串不再需要修改时,及时调用 toString() 方法转换为 String 对象

  5. 注意线程安全:在多线程环境中,确保对 StringBuilder 的操作是线程安全的

  6. 合理使用方法:根据具体需求选择合适的方法,如 append()insert()delete()

总结

StringBuilderStringBuffer 是 Java 中用于处理可变字符串的类,它们的主要特点:

  1. 可变性:可以在不创建新对象的情况下修改字符串内容

  2. 性能:比 String 类在字符串拼接和修改操作上性能更高

  3. 区别

    • StringBuilder:非线程安全,性能较高
    • StringBuffer:线程安全,性能较低
  4. 应用场景

    • 大量字符串拼接
    • 频繁的字符串修改操作
    • 多线程环境(使用 StringBuffer

通过合理使用 StringBuilderStringBuffer,可以提高代码的性能和可维护性。

© 2026 编程马·菜鸟教程 版权所有