java - Java String.join 但还在末尾添加分隔符
问题描述
我有数组["a", "b", "c"]
,我想将它们连接在一起形成“a#b#c#”。String.join 只会让我得到“a#b#c”。我不能这样做str += "#"
,因为这很慢(Java 必须创建一个新字符串才能做到这一点)。因此,我必须使用StringBuilder
. 是否有一些 Java 有基本上是 String.join 但也将分隔符附加到末尾的方法?
对于更多的上下文,我正在尝试使用一组字符串创建一个 Suffix Array 数据结构,因此这部分实际上是一个瓶颈。
解决方案
您可以使用 Stream API Collectors.joining() 有这样的前缀和后缀参数:
Stream.of("a", "b", "c")
.collect(Collectors.joining("#", "", "#"));
其中加入参数分别是分隔符、前缀、后缀。
此外,您可以像上面评论中的@Wander Nauta 所说的那样向您的数组添加一个空字符串
我已经启动了 JMH,并重现了 如下所示的性能差异:
public class Benchmarks {
private static final String[] arr = {"a", "b", "c"};
@Benchmark
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 1, warmups = 1)
@BenchmarkMode(Mode.AverageTime)
public String joinAndConcat() {
return String.join("#", arr) + "#";
}
@Benchmark
@Fork(value = 1, warmups = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public String streamsJoining() {
return Stream.of(arr)
.parallel()
.collect(Collectors.joining("#", "", "#"));
}
@Benchmark
@Fork(value = 1, warmups = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public String stringJoiner() {
StringJoiner joiner = new StringJoiner("#", "", "#");
for (String el : arr) {
joiner.add(el);
}
return joiner.toString();
}
}
结果:
> Benchmark Mode Cnt Score Error Units
> Benchmarks.joinAndConcat avgt 5 46,670 ± 0,139 ns/op
> Benchmarks.streamsJoining avgt 5 73,336 ± 0,180 ns/op
> Benchmarks.stringJoiner avgt 5 27,236 ± 0,386 ns/op
但是您必须了解,nSec
对于大多数应用程序来说,46 是一个非常小的差异。
推荐阅读
- java - 具有不同 jdk 版本的 jenkins 管道
- r - 如何在 ggplot2 的多面图的单个标签中使用特殊字符、上标或下标?
- node.js - 图像和 css 不适用于 Handlebars
- compiler-errors - 从在 X86 上运行的 Ubuntu 交叉编译 C 程序到 Alpha ISA
- c# - 如何禁止用户在 Windows 窗体中将窗体拖动到屏幕边缘之外
- blockchain - Truffle 迁移未部署到 Ganache
- python - Python 套接字绑定报告端口已被使用,但套接字 connect_ex 返回 0
- azure - 有什么方法可以使用日志在 Azure Kubernetes 服务 (AKS) 上找到节点可伸缩时间?
- c# - 如何使用图形 API c# 过滤 MS Teams 频道以及为频道配置的连接器
- java - 用于电子邮件的 Snapdeal Selenium 自动化和用于谷歌登录的下一步按钮