介绍
StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾。虽然这也可以在StringBuilder类的帮助下在每个字符串之后附加分隔符,但StringJoiner提供了简单的方法来实现,而无需编写大量代码。
StringJoiner类共有2个构造函数,5个公有方法。其中最常用的方法就是add方法和toString方法,类似于StringBuilder中的append方法和toString方法。
用法
StringJoiner的用法比较简单,下面的代码中,我们使用StringJoiner进行了字符串拼接。
public class StringJoinerTest {
public static void main(String[] args) {
StringJoiner sj = new StringJoiner("Hello");
sj.add("World");
sj.add("Java");
System.out.println(sj.toString());
StringJoiner sj1 = new StringJoiner(":", "[", "]");
sj1.add("Hello").add("World").add("Java");
System.out.println(sj1.toString());
}
}
以上代码输出结果:
WorldHelloJava
[Hello:World:Java]
注意
值得注意的是,当我们StringJoiner(CharSequence delimiter)初始化一个StringJoiner的时候,这个delimiter其实是分隔符,并不是可变字符串的初始值。
StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)的第二个和第三个参数分别是拼接后的字符串的前缀和后缀。
原理
介绍了简单的用法之后,我们再来看看这个StringJoiner的原理,看看他到底是如何实现的。主要看一下add方法:
public StringJoiner add(CharSequence newElement) {
prepareBuilder().append(newElement);
return this;
}
private StringBuilder prepareBuilder() {
if (value != null) {
value.append(delimiter);
} else {
value = new StringBuilder().append(prefix);
}
return value;
}
看到了一个熟悉的身影——StringBuilder ,没错,StringJoiner其实就是依赖StringBuilder实现的
当我们发现StringJoiner其实是通过StringBuilder实现之后,我们大概就可以猜到,他的性能损耗应该和直接使用StringBuilder差不多!
为什么需要StringJoiner
在了解了StringJoiner的用法和原理后,可能很多读者就会产生一个疑问,明明已经有一个StringBuilder了,为什么Java 8中还要定义一个StringJoiner呢?到底有什么好处呢?
如果读者足够了解Java 8的话,或许可以猜出个大概,这肯定和Stream有关。
作者也在Java doc中找到了答案:
A StringJoiner may be employed to create formatted output from a Stream using Collectors.joining(CharSequence)
试想,在Java中,如果我们有这样一个List:
List<String> list = ImmutableList.of("Hello","World","Java");
如果我们想要把他拼接成一个以下形式的字符串:
Hello,World,Java
为了满足类似这样的需求,Java 8中提供的StringJoiner就派上用场了。以上需求只需要一行代码:
list.stream().collect(Collectors.joining(")
即可。上面用的表达式中,Collectors.joining的源代码如下:
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
其实现原理就是借助了StringJoiner。
当然,或许在Collector中直接使用StringBuilder似乎也可以实现类似的功能,只不过稍微麻烦一些。所以,Java 8中提供了StringJoiner来丰富Stream的用法。
而且StringJoiner也可以方便的增加前缀和后缀,比如我们希望得到的字符串是[Hello,World,Java]而不是Hello,World,Java的话,StringJoiner的优势就更加明显了。
总结
本文介绍了Java 8中提供的可变字符串类——StringJoiner,可以用于字符串拼接。
StringJoiner其实是通过StringBuilder实现的,所以他的性能和StringBuilder差不多,他也是非线程安全的。
如果日常开发中中,需要进行字符串拼接,如何选择?
1、如果只是简单的字符串拼接,考虑直接使用”+”即可。
2、如果是在for循环中进行字符串拼接,考虑使用StringBuilder和StringBuffer。
3、如果是通过一个List进行字符串拼接,则考虑使用StringJoiner。
结语
欢迎关注微信公众号『码仔zonE』,专注于分享Java、云计算相关内容,包括SpringBoot、SpringCloud、微服务、Docker、Kubernetes、Python等领域相关技术干货,期待与您相遇!