介绍

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等领域相关技术干货,期待与您相遇!

Java 8中字符串拼接新姿势:StringJoiner的更多相关文章

  1. javascript中字符串拼接详解

    字符串拼接是所有程序设计语言都需要的操作.当拼接结果较长时,如何保证效率就成为一个很重要的问题.本文介绍的是Javascript中的字符串拼接,希望对你有帮助,一起来看.   最近在研究<jav ...

  2. 【转】Java 5种字符串拼接方式性能比较。

    最近写一个东东,可能会考虑到字符串拼接,想了几种方法,但对性能未知,于是用Junit写了个单元测试. 代码如下: import java.util.ArrayList; import java.uti ...

  3. Java 5种字符串拼接方式性能比较

    http://blog.csdn.net/kimsoft/article/details/3353849 import java.util.ArrayList; import java.util.Li ...

  4. Java 5种字符串拼接方式性能比较。

    最近写一个东东,可能会考虑到字符串拼接,想了几种方法,但对性能未知,于是用Junit写了个单元测试. 代码如下: import java.util.ArrayList; import java.uti ...

  5. Python中字符串拼接的N种方法

    python拼接字符串一般有以下几种方法: ①直接通过(+)操作符拼接 s = 'Hello'+' '+'World'+'!'print(s) 输出结果:Hello World! 使用这种方式进行字符 ...

  6. SQL中字符串拼接

    1. 概述 在SQL语句中经常需要进行字符串拼接,以sqlserver,oracle,mysql三种数据库为例,因为这三种数据库具有代表性. sqlserver: select '123'+'456' ...

  7. ECMASCRIPT 6中字符串的新特性

    本文将覆盖在ECMAScript 6 (ES6)中,字符串的新特性. Unicode 码位(code point)转义 Unicode字符码位的长度是21位[2].而JavaScript的字符串,是1 ...

  8. Python中字符串拼接的三种方式

    在Python中,我们经常会遇到字符串的拼接问题,在这里我总结了三种字符串的拼接方式:     1.使用加号(+)号进行拼接 加号(+)号拼接是我第一次学习Python常用的方法,我们只需要把我们要加 ...

  9. CTE 中字符串拼接

    1>cte语法 1.1>基础语句和递归语句中必须有字段 1.2>最后只能跟一条查询语句 1.3>字符串拼接,要将拼接的字段转成字符串类型,cast(fieldName as n ...

随机推荐

  1. ecshop v2 v3 EXP

    import requests import binascii def get_v2Payload(code): '''Ecshop V2.x payload''' code = "{$ab ...

  2. 学习JUC源码(3)——Condition等待队列(源码分析结合图文理解)

    前言 在Java多线程中的wait/notify通信模式结尾就已经介绍过,Java线程之间有两种种等待/通知模式,在那篇博文中是利用Object监视器的方法(wait(),notify().notif ...

  3. C#发送腾讯企业邮箱

    腾讯企业邮箱客户端配置介绍 http://email-qq.cn/tengxun/201610303793.html?akvezc=smt0n2 POP3/SMTP协议 POP3/SMTP协议: 接收 ...

  4. MES系统介绍

    为什么要引入MES系统? 随着ERP在企业应用的深入,ERP系统逐渐显示出其局限性.当ERP下达的工单到生产现场后,产品制造是以产线 "工单"或"批次"(Bat ...

  5. Solon 特性简集,相较于 Springboot 有什么区别?

    Solon 是一个类似Springboot的微型开发框架,也是一个不基于Servlet的开发框架.项目从2018年启动以来,参考过大量前人作品:历时两年,3500多次的commit:内核保持0.1m的 ...

  6. element-ui 表单 v-if 不能验证问题

    element-ui 表单v-if 很多人会遇到无法验证的问题,网上很多是在el-form-item标签前加一个div然后把v-if拿到div上去像这样 <div v-if="addc ...

  7. [leetcode]55.JumpGame动态规划题目:跳数游戏

    /** * Given an array of non-negative integers, you are initially positioned at the first index of th ...

  8. Redis中的常用命令哪些?

    a.hset 存储一个哈希键值对的集合 b.hget获取一个哈希键的值c.hdel 删除一个或多个字段 d.hgetall 获取一个哈希是键值对的集合 e.lpush key value向链表左侧添加 ...

  9. JavaDailyReports10_11

    ********************************** 验证码 AWT Swing 1 package nanshen; 2 3 import java.awt.Container; 4 ...

  10. Kafka 消费组消费者分配策略

    body { margin: 0 auto; font: 13px / 1 Helvetica, Arial, sans-serif; color: rgba(68, 68, 68, 1); padd ...