0
点赞
收藏
分享

微信扫一扫

Java——StringJoiner

一葉_code 2022-03-11 阅读 47


简介

public final class StringJoiner
extends Object

StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾。虽然这也可以在StringBuilder类的帮助下在每个字符串之后附加分隔符,但StringJoiner提供了简单的方法来实现,而无需编写大量代码。

​StringJoiner​​​用于构造由分隔符分隔的字符序列,并且可选地从提供的前缀开始并以提供的后缀结尾。在此之前添加一些东西到​​StringJoiner​​​ ,其​​sj.toString()​​​方法,默认情况下,返回​​prefix + suffix​​​ 。 但是,如果调用了​​setEmptyValue​​​方法,则将返回提供的​​emptyValue​​​ 。 这可用于,例如,使用一组表示法来表示空集,即创建字符串时​​"{}"​​​ ,其中​​prefix​​​是​​"{"​​​时, ​​suffix​​​是​​"}"​​​和什么已被添加到​​StringJoiner​​ 。

注意:StringJoiner其实是通过StringBuilder实现的,所以它的性能和StringBuilder差不多,它也是非线程安全的。 

字符串​​"[George:Sally:Fred]"​​可以构造如下:

StringJoiner sj = new StringJoiner(":", "[", "]");
sj.add("George").add("Sally").add("Fred");
String desiredString = sj.toString();

日常开发中需要进行字符串拼接,如何选择


  1. 如果只是简单的字符串拼接,考虑直接使用"+"即可。
  2. 如果是在for循环中进行字符串拼接,考虑使用StringBuilder和StringBuffer。
  3. 如果是通过一个集合(如List)进行字符串拼接,则考虑使用StringJoiner。
  4. 如果是对一组数据进行拼接,则可以考虑将其转换成Stream,并使用StringJoiner处理。

构造方法


构造方法和描述

​​StringJoiner​​(​​CharSequence​​ delimiter)​

构造一个 ​​StringJoiner​​​与其中不带字符,没有 ​​prefix​​​或 ​​suffix​​​ ,以及所提供的副本 ​​delimiter​​ 。


​​StringJoiner​​(​​CharSequence​​ delimiter, ​​CharSequence​​ prefix, ​​CharSequence​​ suffix)​

构造一个 ​​StringJoiner​​​使用的供给拷贝在不带字符 ​​prefix​​​ , ​​delimiter​​​和 ​​suffix​​ 。


注意:


  1. 当我们使用StringJoiner(CharSequence delimiter)初始化一个StringJoiner的时候,​这个delimiter其实是分隔符,并不是可变字符串的初始值。
  2. StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)的第二个和第三个参数分别是拼接后的字符串的前缀和后缀。

提供的方法

最常用的方法就是add方法和toString方法,类似于StringBuilder中的append方法和toString方法。 


修饰和类型

方法和描述

​​StringJoiner​​

​​add​​(​​CharSequence​​ newElement)​

将给定的副本 ​​CharSequence​​​值作为下一个元素 ​​StringJoiner​​值。


​int​

​​length​​()​

返回此 ​​StringJoiner​​​的 ​​String​​表示的长度。


​​StringJoiner​​

​​merge​​(​​StringJoiner​​ other)​

添加给定的 ​​StringJoiner​​的内容,没有前缀和后缀作为下一个元素,如果它是非空的。


​​StringJoiner​​

​​setEmptyValue​​(​​CharSequence​​ emptyValue)​

设置序列的字符时要使用确定的字符串表示的这个 ​​StringJoiner​​ ,而没有单元已被添加然而,就是当它是空的。


​​String​​

​​toString​​()​

返回当前值,由的 ​​prefix​​​ ,值添加由迄今分离 ​​delimiter​​​和 ​​suffix​​​ ,除非没有元素已经在这种情况下,被添加 ​​prefix + suffix​​​或 ​​emptyValue​​被返回的字符


 ​原理

主要看一下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;
}

可以得知StringJoiner其实就是依赖StringBuilder实现的,StringJoiner性能损耗应该和直接使用StringBuilder差不多​

在Java doc中有这样一句话:


A StringJoiner may be employed to create formatted output from a Stream using Collectors.joining(CharSequence)


如果有这样一个List:

List<String> list = ImmutableList.of("Hollis","hollischuang","Java干货");

如果想要把他拼接成一个以下形式的字符串:

Hollis,hollischuang,Java干货

可以通过以下方式:

StringBuilder builder = new StringBuilder();

if (!list.isEmpty()) {
builder.append(list.get(0));
for (int i = 1, n = list.size(); i < n; i++) {
builder.append(",").append(list.get(i));
}
}
builder.toString();

还可以使用:

list.stream().reduce(new StringBuilder(), (sb, s) -> sb.append(s).append(','), StringBuilder::append).toString();

但是输出结果稍有些不同,需要进行二次处理:

Hollis,hollischuang,Java干货,

还可以使用"+"进行拼接:

list.stream().reduce((a,b)->a + "," + b).toString();

以上几种方式,要么是代码复杂,要么是性能不高,或者无法直接得到想要的结果。为了满足类似这样的需求,Java 8中提供的StringJoiner就派上用场了。以上需求只需要一行代码:

list.stream().collect(Collectors.joining(":"))

即可。上面用的表达式中,Collector.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);
}

Collector.joining的实现原理就是借助了StringJoiner,或许在Collector中直接使用StringBuilder似乎也可以实现类似的功能,只不过稍微麻烦一些;所以Java 8提供StringJoiner丰富Stream的用法,而且StringJoiner可以方便的增加前缀和后缀,比如希望得到的字符串是"[Hollis,hollischuang,Java干货]"而不是"Hollis,hollischuang,Java干货"的话,StringJoiner的优势就更加明显了。 


举报

相关推荐

0 条评论