当前位置: 首页 > news >正文

StringBuffer与StringBuilder 2024-8-21 22-13

目录

  • 一、StringBuffer
  • 二、StringBuilder
  • 三、总结

一、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 对象 sharedBufferStringBuffer sharedBuffer = new StringBuffer();// 创建第一个线程 thread1Thread thread1 = new Thread(() -> {// 在这个线程中,循环 1000 次向 sharedBuffer 中追加字符'A'for (int i = 0; i < 1000; i++) {sharedBuffer.append("A");}});// 创建第二个线程 thread2Thread 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

http://www.lryc.cn/news/429494.html

相关文章:

  • 会声会影剪辑视频收费吗,会声会影最新破解版
  • 在Windows11强制开启copilot
  • 基于Java的开源CMS有哪些推荐,各自特点是什么
  • IPC进程通信以及网络通信
  • 【脏数据 bug 解决】ValueError: mean must have 1 elements if it is an iterable, got 3
  • 【Vue3】集成 Ant Design Vue
  • 如何处理前端项目中的SEO优化:从SPA到SSR与SSG
  • 【UE5】Groom毛发系统的基本使用——给小白人添加头发
  • DataWorks函数
  • 设计模式学习优质网站分享:refactoring.guru
  • JVM-Java的四种引用
  • 探索《黑神话:悟空》品质保障的背后:ISO体系认证
  • ArcGIS Pro 实现人口分布栅格TIFF数据的网格提取与可视化
  • select的缺点;poll ;poll的缺点;epoll
  • keli5_报错 Cannot Load Device Description问题
  • 算法的学习笔记—把二叉树打印成多行(牛客JZ78)
  • FreeRTOS 时间管理
  • F. Valuable Cards D. Smithing Skill
  • 【电子通识】IPC-A-600中对验收标准的定义
  • MyBatis(初阶)
  • KDP数据平台:以实战案例验证技术领先力
  • [Linux] 什么是 Shell?
  • 大模型学习应用 2:快速上手大模型基于langchain实现RAG检索应用
  • python环境安装之后,cmd输入python回车会打开微软商店
  • USB Type-C如何取9V、12V、15V、20V电压-PD快充协议芯片ECP5701
  • Go 语言 Map 17
  • 移植bash到openharmony
  • git stash详细教程
  • UDP网络攻击
  • 漏洞扫描的重要性,如何做好漏洞扫描服务