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

String、StringBuilder、StringBuffer 学习与深入

1 学习的知识是什么

String:字符串,一旦创建里面的内容就不可变,每次使用+拼接都创建一个新的对象而原有的对象依旧存在。
StringBuilder:可变字符串线程不安全,每次拼接字符串只会在字符串后面追加字符而不是创建新的对象,字符串可修改。

StringBuffer:可变字符串线程安全,每次拼接字符串只会在字符串后面追加字符而不是创建新的对象,字符串可修改。

2. 三者的字符串特性

1.String每次拼接都会创建新的对象,StringBuffer,StringBuilder不会

2.StringBuffer,StringBuilder可以对字符串进行各种操作

package com.se.string; /*** * date:2026/5.11 */ public class StringTest { public static void main(String[] args) { String str = "hello"; System.out.println("打印:"+System.identityHashCode(str));//打印:460141958 str+= "world"; System.out.println("打印:"+System.identityHashCode(str));//打印:1163157884 //String的地址不同说明不是同一个对象 StringBuilder sbd = new StringBuilder("hello"); System.out.println("打印:"+System.identityHashCode(sbd));//打印:1956725890 sbd.append("world"); System.out.println("打印:"+System.identityHashCode(sbd));//打印:1956725890 //StringBuilder的地址一样说明是同一个对象 StringBuffer sbf = new StringBuffer("hello"); System.out.println("打印:"+System.identityHashCode(sbf));//打印:356573597 sbf.append("world"); System.out.println("打印:"+System.identityHashCode(sbf));//打印:356573597 //StringBuffer的地址一样说明是同一个对象 //这些方法StringBuffer,StringBuilder都一样,唯一的区别是StringBuffer的方法都加了synchronized所以线程安全,不过效率慢一点 //1.append();在字符串后面追加字符 sbf.append(1); System.out.println(sbf);//打印:helloworld1 //2.insert();在字符串中间插入字符 sbf.insert(6,"StringBuffer"); System.out.println(sbf);//打印:helloStringBufferworld1 从0开始算位置 //3.delete(start,end);删除字符串中间的字符 sbf.delete(5,12); System.out.println(sbf);//打印:helloworld1 //4.replace(start,end,chars);字符串替换 sbf.replace(5,11,"StringBuffer"); System.out.println(sbf);//打印:helloStringBufferworld1 //5.reverse();反转字符串 sbf.reverse(); System.out.println(sbf);//打印:1dlrowgnitpircSihell //6.toString();将StringBuffer转换为String String str1 = sbf.toString(); System.out.println(str1);//打印:1dlrowgnitpircSihell } }

3. StringBuffer和StringBuilder的安全性分析

3.1性能分析

1.在单线程环境下StringBuilder的性能优于StringBuffer

2.在多线程环境下StringBuffer的安全性可以得到保证

3.以上原因是StringBuffer的所有方法是被synchronized修饰的

package com.se.string; public class StringTest2 { public static int COUNT = 1000000; public static void main(String[] args) { // 预热 JVM warmUp(); // StringBuilder long start1 = System.currentTimeMillis(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < COUNT; i++) { sb.append("a"); } long time1 = System.currentTimeMillis() - start1; // StringBuffer long start2 = System.currentTimeMillis(); StringBuffer sbf = new StringBuffer(); for (int i = 0; i < COUNT; i++) { sbf.append("a"); } long time2 = System.currentTimeMillis() - start2; System.out.println("StringBuilder 耗时:" + time1 + "ms");//StringBuilder 耗时:17ms System.out.println("StringBuffer 耗时:" + time2 + "ms");//StringBuffer 耗时:27ms System.out.println("StringBuffer 比 StringBuilder 慢约 " + (time2 - time1) + "ms");//StringBuffer 比 StringBuilder 慢约 10ms } // JVM 预热,让后续测试更稳定 private static void warmUp() { for (int k = 0; k < 10; k++) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append(i); } } } }

实际来看在单线程场景下两种的效率差别不大,用stringbuilder更多只是为了满足规范---这是在单线程场景下使用

3.2 线程安全

1. 开启10个线程,每个线程都添加1000个a,然后查看是否添加够了10000个a

package com.se.string; public class StringTest3 { private static final int THREAD_COUNT = 10; private static final int APPEND_COUNT = 1000; public static void main(String[] args) throws InterruptedException { // 测试 StringBuilder(线程不安全) StringBuilder sb = new StringBuilder(); Thread[] threads1 = new Thread[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { threads1[i] = new Thread(() -> { for (int j = 0; j < APPEND_COUNT; j++) { sb.append("a"); } }); threads1[i].start(); } for (Thread t : threads1) { t.join(); // 等所有线程执行完 } System.out.println("StringBuilder 预期长度:" + (THREAD_COUNT * APPEND_COUNT));//StringBuilder 预期长度:10000 System.out.println("StringBuilder 实际长度:" + sb.length());//StringBuilder 实际长度:5423 System.out.println("---------------"); // 测试 StringBuffer(线程安全) StringBuffer sbf = new StringBuffer(); Thread[] threads2 = new Thread[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { threads2[i] = new Thread(() -> { for (int j = 0; j < APPEND_COUNT; j++) { sbf.append("a"); } }); threads2[i].start(); } for (Thread t : threads2) { t.join(); } System.out.println("StringBuffer 预期长度:" + (THREAD_COUNT * APPEND_COUNT));//StringBuffer 预期长度:10000 System.out.println("StringBuffer 实际长度:" + sbf.length());//StringBuffer 实际长度:10000 } }

因为stringbuffer带锁所以线程是安全的,而stringBuilder没有锁所以数据会丢失

http://www.jsqmd.com/news/800955/

相关文章:

  • Bitloops:用业务逻辑即代码革新复杂系统开发
  • 体系认证咨询公司如何选?中安质环认证江苏中心靠谱吗? - 工业品牌热点
  • 构建本地语音智能体:基于Go与OpenClaw的实时交互系统
  • 选购模具设计服务有哪些要点? - mypinpai
  • PID调参总调不好?试试用Simulink的自动整定工具,5分钟找到最优参数
  • 从“能用”到“可靠”:基于SonarQube与Jenkins的Java代码质量防线构建实战
  • 选购无人机培训包就业服务,如何选择 - 工业品牌热点
  • 别再只懂PCA了!用Python手写LDA,从鸢尾花分类实战看监督降维的威力
  • 3步实现iOS设备虚拟定位:跨平台工具完全指南
  • 不想卷开发了!程序员 90 天转行网安学习路线完整版
  • GitHub 被分号击穿信任防线,AI 逆向工具敲响闭源系统安全警钟
  • 2026年中国靠谱的模具设计公司排名:寅动智能有实力吗? - mypinpai
  • 3步掌握NBTExplorer:从Minecraft数据恐惧到编辑专家的完整指南
  • NAND闪存市场演进:从消费电子到AI时代的技术博弈与产业洞察
  • 口碑好的无人机培训包就业公司推荐——华研科技 - 工业品牌热点
  • ARM A64指令集架构解析与优化实践
  • 别再傻傻分不清TPS和QPS了!性能测试新手必看的5个核心指标实战解读
  • 知识蒸馏与Koopman算子结合的神经网络线性化方法
  • 2026年宁波首饰黄金回收费用,宁波瑞谨奢侈品口碑不错 - mypinpai
  • 5分钟搞定Windows风扇控制:FanControl让你的电脑散热更智能更安静
  • 2026年浙江泰平主要做光缆配线架吗?口碑怎么样? - mypinpai
  • 终极maya-glTF导出攻略:从3D建模到Web 3D的无缝转换秘籍
  • 别再被异常值带偏了!聊聊机器学习中稳健回归的‘抗揍’算法:IRLS
  • 直播人力成本居高不下?2026十大AI数字人直播平台推荐实现长效运营
  • 苏皖江虎再生资源回收报废多联机组中央空调怎么样 - 工业品牌热点
  • 从2012年ACE奖看电子产业创新:Zynq、CMOS振荡器与混合域示波器的启示
  • 【 Godot 4 学习笔记】资源路径
  • 如何3分钟获取百度网盘提取码:智能工具实战指南
  • 北京智源联合多机构发布FlagSafe大模型安全体系,为AI发展保驾护航
  • Pro UI Engineering Skill:让AI生成专业级UI的工程化设计规范指南