StringBuffer与StringBuilder 2024-8-21 22-13

一、StringBuffer

StringBuffer是一个可变的字符序列,它的存在是为了解决频繁操作字符串时产生大量临时对象的问题。

  1. 构造方法

    • StringBuffer():创建一个空的字符串缓冲区,初始容量为 16 个字符。
    • StringBuffer(int capacity):创建一个空的字符串缓冲区,具有指定的初始容量
    • StringBuffer(String str):创建一个字符串缓冲区,并将其初始内容设置为指定的字符串。
  2. 常用方法

    • append():将指定的参数追加到字符串缓冲区的末尾。可以接受各种数据类型的参数,如基本数据类型、字符串、对象等。例如:
      StringBuffer sb = new StringBuffer("Hello");
      sb.append(" World!");
      System.out.println(sb); // 输出:Hello World!
      
    • insert():在指定位置插入指定的参数。例如:
      StringBuffer sb = new StringBuffer("Hello");
      sb.insert(2, "abc");
      System.out.println(sb); // 输出:Heabcllo
      
    • delete():删除指定范围内的字符。例如:
      StringBuffer sb = new StringBuffer("Hello World!");
      sb.delete(5, 11);//左闭右开
      System.out.println(sb); // 输出:Hello!
      
    • reverse():将字符串缓冲区中的字符序列反转。例如:
      StringBuffer sb = new StringBuffer("Hello");
      sb.reverse();
      System.out.println(sb); // 输出:olleH
      
    • length():返回字符串缓冲区的长度。
    • capacity():返回当前字符串缓冲区的容量。如果需要的字符数量超过当前容量,StringBuffer会自动增加容量。
  3. 线程安全性

StringBuffer线程安全的,这意味着多个线程可以同时访问和操作同一个StringBuffer对象,而不会出现数据不一致的情况。这是通过在方法上进行同步实现的。例如:

class ThreadSafeExample {
    public static void main(String[] args) {
        // 创建一个空的 StringBuffer 对象 sharedBuffer
        StringBuffer sharedBuffer = new StringBuffer();

        // 创建第一个线程 thread1
        Thread thread1 = new Thread(() -> {
            // 在这个线程中,循环 1000 次向 sharedBuffer 中追加字符'A'
            for (int i = 0; i < 1000; i++) {
                sharedBuffer.append("A");
            }
        });

        // 创建第二个线程 thread2
        Thread thread2 = new Thread(() -> {
            // 在这个线程中,循环 1000 次向 sharedBuffer 中追加字符'B'
            for (int i = 0; i < 1000; i++) {
                sharedBuffer.append("B");
            }
        });

        // 启动第一个线程
        thread1.start();
        // 启动第二个线程
        thread2.start();

        try {
            // 等待第一个线程执行完毕
            thread1.join();
            // 等待第二个线程执行完毕
            thread2.join();
        } catch (InterruptedException e) {
            // 如果在等待过程中被中断,打印异常信息
            e.printStackTrace();
        }

        // 输出 sharedBuffer 的长度
        System.out.println(sharedBuffer.length());
    }
}

这段代码创建了两个线程,分别向同一个StringBuffer对象中追加不同的字符。通过使用join()方法,确保主线程等待两个子线程执行完毕后再输出StringBuffer的长度。

  1. 适用场景

当需要在多线程环境下操作字符串时,StringBuffer是一个合适的选择。例如,在一个多线程的服务器应用程序中,多个线程可能需要同时构建一个响应字符串,这时使用StringBuffer可以确保数据的一致性。

二、StringBuilder

StringBuilderStringBuffer类似,也是一个可变的字符序列,但它是非线程安全的。

  1. 构造方法

    • StringBuilder():创建一个空的字符串生成器,初始容量为 16 个字符。
    • StringBuilder(int capacity):创建一个空的字符串生成器,具有指定的初始容量
    • StringBuilder(String str):创建一个字符串生成器,并将其初始内容设置为指定的字符串。
  2. 常用方法

StringBuffer的方法基本相同,包括append()insert()delete()reverse()等。例如:

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World!");
System.out.println(sb); // 输出:Hello World!
  1. 性能优势

由于StringBuilder不需要进行线程同步,所以在单线程环境下,它的性能通常比StringBuffer更高。例如:

// 获取当前系统时间(以毫秒为单位),用于记录开始时间
long startTime = System.currentTimeMillis();
// 创建一个 StringBuilder 对象
StringBuilder sb = new StringBuilder();
// 循环 100000 次
for (int i = 0; i < 100000; i++) {
    // 将循环变量 i 追加到 StringBuilder 对象 sb 中
    sb.append(i);
}
// 再次获取当前系统时间,计算从开始到现在经过的时间,并打印使用 StringBuilder 的操作时间
System.out.println("StringBuilder time: " + (System.currentTimeMillis() - startTime));

// 再次获取当前系统时间(以毫秒为单位),用于记录新的开始时间
startTime = System.currentTimeMillis();
// 创建一个 StringBuffer 对象
StringBuffer sbf = new StringBuffer();
// 循环 100000 次
for (int i = 0; i < 100000; i++) {
    // 将循环变量 i 追加到 StringBuffer 对象 sbf 中
    sbf.append(i);
}
// 再次获取当前系统时间,计算从这个新的开始时间到现在经过的时间,并打印使用 StringBuffer 的操作时间
System.out.println("StringBuffer time: " + (System.currentTimeMillis() - startTime));

分别使用StringBuilderStringBuffer进行大量的字符串拼接操作,可以看到StringBuilder的执行时间通常更短。

  1. 适用场景

在单线程环境下,当需要高效地操作字符串时,StringBuilder是一个很好的选择。例如,在一个桌面应用程序中,只有一个主线程在操作字符串,这时使用StringBuilder可以提高性能。

三、总结

StringBufferStringBuilder都是 Java 中用于操作可变字符串的工具类。它们的主要区别在于线程安全性性能StringBuffer是线程安全的,但性能相对较低;StringBuilder是非线程安全的,但在单线程环境下性能更高。在选择使用哪个类时,需要根据具体的应用场景来决定。如果是在多线程环境下操作字符串,应该使用StringBuffer;如果是在单线程环境下,为了获得更好的性能,可以选择使用StringBuilder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值