最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。
【重磅发布】《Spring Boot 3实战案例锦集》PDF电子书现已出炉!
🎉🎉我们精心打造的《Spring Boot 3实战案例锦集》PDF电子书现已正式完成,目前已经有70个案例,后续还将继续更新。文末有电子书目录。
📚📚订阅获取:
只需订阅我们的合集《点我订阅》,即可立即私信我们获取这本珍贵的电子书。轻松拥有Spring Boot 3的实战宝典!
💪💪永久更新承诺:
我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务。这意味着,随着技术的不断发展和Spring Boot 3的深入应用,我们的电子书也将持续更新,确保您始终掌握最前沿、最实用的技术知识。
🔥🔥精彩内容不容错过:
《Spring Boot 3实战案例锦集》汇聚了众多精心挑选的实战案例,旨在帮助您快速掌握Spring Boot 3的核心技术和实战技巧。无论您是初学者还是有一定经验的开发者,都能从中受益匪浅。
💌💌如何获取:
请立即订阅我们的合集《点我订阅》,并通过私信联系我们,我们将第一时间将电子书发送给您。
环境:SpringBoot3.2.5
1. 简介
在开发中,字符串拼接是非常常见的操作,广泛应用于日志记录、数据处理、用户界面生成等场景。然而,不同的字符串拼接方式在性能上有着显著的差异,这一点往往被开发人员忽视。本文将详细介绍 Java 中的 8 种字符串拼接方式,并通过性能测试揭示这些方法的实际表现,结果令人意外。
Java中可以使用如下8种方式进行字符串的拼接:
"+"操作符
String#concat方法
String#join方法
String#format方法
Stream流方式
StringBuffer
StringBuilder
StringJoiner
我们将通过JMH进行性能的测试,所以如果你对JMH还不熟悉的,你可以查看下面这篇文章:
下面我们依次介绍这8中方式;接下来的示例我们都将建立在JMH之上。
2. 实战案例
2.1 "+"操作符
这是最简单的方法,也是我们可能最熟悉的一种。它可以使用加号(+)运算符来连接字符串字面量、变量或者二者的组合:
public void plusOperator(Blackhole hole) {String str1 = "Pack";String str2 = " xxxooo";String result = str1 + str2;hole.consume(result);}
2.2 String#concat方法
concat() 方法由 String 类提供,可用于将两个字符串连接在一起。
public void concat(Blackhole hole) {String str1 = "Pack";String str2 = " xxxooo";String result = str1.concat(str2);hole.consume(result);}
2.3 String#join方法
String.join() 是 Java 8 以后新增的静态方法。它允许使用指定的分隔符连接多个字符串。
public void join(Blackhole hole) {String str1 = "Pack";String str2 = " xxxooo";String result = String.join("", str1, str2);hole.consume(result);}
2.4 String#format方法
String.format() 用于使用占位符和格式指定符格式化字符串。通过使用实际值替换占位符,可以创建格式化字符串。
public void format(Blackhole hole) {String str1 = "Pack";String str2 = " xxxooo";String result = String.format("%s%s", str1, str2);hole.consume(result);}
2.5 Stream流
它为在对象集合上执行操作提供了一种富有表现力的方法,并允许我们使用 Collectors.joining() 来集中字符串。
public void stream(Blackhole hole) {List<String> strList = Arrays.asList("Pack", " xxxooo");String result = strList.stream().collect(Collectors.joining());hole.consume(result);}
2.6 StringBuffer
StringBuffer 提供了一个可变的字符序列。它允许对字符串进行动态操作而无需创建新的对象。值得一提的是,它被设计为线程安全的,这意味着它可以被多个线程安全地并发访问和修改。
public void stringBuffer(Blackhole hole) {StringBuffer buffer = new StringBuffer();buffer.append("Pack") ;buffer.append(" xxxooo") ;String result = buffer.toString() ;hole.consume(result) ;}
2.7 StringBuilder
StringBuilder 和 StringBuffer 的用途相同。它们之间唯一的区别是 StringBuilder 不是线程安全的,而 StringBuffer 是。在不需要考虑线程安全的单线程场景中,StringBuilder 是非常完美的选择。
public void stringBuilder(Blackhole hole) {StringBuilder builder = new StringBuilder() ;builder.append("Pack") ;builder.append(" xxxooo") ;String result = builder.toString() ;hole.consume(result) ;}
2.8 StringJoiner
StringJoiner 是从 Java 8 开始引入的一个新类。它的功能与 StringBuilder 类似,提供了一种使用分隔符连接多个字符串的方式。尽管它与 StringBuilder 有相似之处,但 StringJoiner 也不是线程安全的。
@Benchmarkpublic void stringJoiner(Blackhole hole) {StringJoiner joiner = new StringJoiner("");joiner.add("Pack") ;joiner.add(" xxxooo") ;String result = joiner.toString() ;hole.consume(result) ;}
以上我们简单的介绍了每一种字符串拼接的使用。
3. 性能测试
接下来,我们通过JMH进行性能的测试,首先我们在类上添加如下的注解:
// 预热1s钟,预热3次// 启动多少个进程// 指定显示结果(枚举值)// 指定显示结果单位(枚举值)// 迭代10次,每次2spublic class StringJoinTest {// 上面8种字符串拼接的方法}
在本示例中,我们将通过main的方式运行,这种方式稍微有点不是特别准确,你可以选择jar的方式。
public static void main(String[] args) throws Exception {Options options = new OptionsBuilder()// 你要测试的类.include(StringJoinTest.class.getSimpleName())// 启动几个进程.forks(1).build();new Runner(options).run();}
最终测试结果如下:

下面是对上面每一列的说明(以第一行concat测试为例说明)
Benchmark
说明:基准测试的名称,通常是类名+方法名。
示例:StringJoinTest.concat。
Mode
说明:基准测试的模式,常见模式有:
avgt:平均时间模式(Average Time),每个操作的平均时间。
thrpt:吞吐量模式(Throughput),单位时间内完成的操作次数。
sample:采样模式,用于收集详细的统计信息。
ss:稳定状态模式,用于评估长时间运行的性能稳定性。
示例:avgt
Cnt
说明:迭代次数,即基准测试运行的次数。
示例:10
Score
说明:基准测试的主要结果指标。根据模式的不同,这个值的含义也不同。
avgt:每个操作的平均时间(秒、毫秒、纳秒等)。
thrpt:每秒完成的操作次数(ops/s)。
示例:8.584
Error
说明:结果的标准误差(Standard Error),表示结果的不确定性。
示例:0.175
Units
说明:结果的单位
示例:ns/op(每操作纳秒)
基准测试结果来看,"+"加操作符是最高效的,String#format方法是最慢的。
性能排序
(+)plusOperator:6.154 ± 0.119 ns/op
concat:8.584 ± 0.175 ns/op
stringBuilder:11.560 ± 0.216 ns/op
stringBuffer:12.340 ± 0.150 ns/op
stringJoiner:29.932 ± 0.236 ns/op
join:28.210 ± 0.241 ns/op
stream:34.293 ± 0.284 ns/op
format:409.691 ± 2.941 ns/op
以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
推荐文章
你以为只有Controller一种接口定义方式?详解Web函数式接口
解锁Spring资源Resource的强大功能,提升开发效率
SpringBoot参数验证@Validated和@Valid分清楚了吗?这些验证细节你知道吗?



















