Java 8中字符串拼接新姿式:StringJoiner

GitHub 1.3k Star 的Java工程师成神之路 ,不来了解一下吗?html

为何阿里巴巴不建议在for循环中使用”+”进行字符串拼接一文中,咱们介绍了几种Java中字符串拼接的方式,以及优缺点。其中还有一个重要的拼接方式我没有介绍,那就是Java 8中提供的StringJoiner ,本文就来介绍一下这个字符串拼接的新兵。java

若是你想知道一共有多少种方法能够进行字符串拼接,教你一个简单的办法,在Intellij IDEA中,定义一个Java Bean,而后尝试使用快捷键自动生成一个toString方法,IDEA会提示多种toString生成策略可供选择。git

目前我使用的IDEA的toString生成策略默认的是使用JDK 1.8提供的StringJoiner。github

介绍

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

StringJoiner类共有2个构造函数,5个公有方法。其中最经常使用的方法就是add方法和toString方法,相似于StringBuilder中的append方法和toString方法。安全

用法

StringJoiner的用法比较简单,下面的代码中,咱们使用StringJoiner进行了字符串拼接。oracle

public class StringJoinerTest {

    public static void main(String[] args) {
        StringJoiner sj = new StringJoiner("Hollis");

        sj.add("hollischuang");
        sj.add("Java干货");
        System.out.println(sj.toString());

        StringJoiner sj1 = new StringJoiner(":","[","]");

        sj1.add("Hollis").add("hollischuang").add("Java干货");
        System.out.println(sj1.toString());
    }
}
复制代码

以上代码输出结果:app

hollischuangHollisJava干货
[Hollis:hollischuang: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实现的,在为何阿里巴巴不建议在for循环中使用”+”进行字符串拼接中咱们介绍过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("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(":"))
复制代码

便可。上面用的表达式中,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也能够方便的增长前缀和后缀,好比咱们但愿获得的字符串是[Hollis,hollischuang,Java干货]而不是Hollis,hollischuang,Java干货的话,StringJoiner的优点就更加明显了。

总结

本文介绍了Java 8中提供的可变字符串类——StringJoiner,能够用于字符串拼接。

StringJoiner实际上是经过StringBuilder实现的,因此他的性能和StringBuilder差很少,他也是非线程安全的。

若是平常开发中中,须要进行字符串拼接,如何选择?

一、若是只是简单的字符串拼接,考虑直接使用"+"便可。

二、若是是在for循环中进行字符串拼接,考虑使用StringBuilderStringBuffer

三、若是是经过一个List进行字符串拼接,则考虑使用StringJoiner

GitHub 1.3k Star 的Java工程师成神之路 ,不来了解一下吗?

GitHub 1.3k Star 的Java工程师成神之路 ,真的不来了解一下吗?

GitHub 1.3k Star 的Java工程师成神之路 ,真的肯定不来了解一下吗?

相关文章
相关标签/搜索