来自:Hollis(微信号:hollischuang)

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

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


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

1

介绍

StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾。

虽然这也可以在StringBuilder类的帮助下在每个字符串之后附加分隔符,但StringJoiner提供了简单的方法来实现,而无需编写大量代码。

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

2

用法

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

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());
    }
}

以上代码输出结果:

hollischuangHollisJava干货[Hollis:hollischuang:Java干货]

值得注意的是,当我们使用StringJoiner(CharSequence delimiter)初始化一个StringJoiner的时候,这个delimiter其实是分隔符,并不是可变字符串的初始值。

StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)的第二个和第三个参数分别是拼接后的字符串的前缀和后缀。

3

原理

介绍了简单的用法之后,我们再来看看这个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实现之后,我们大概就可以猜到,StringJoiner性能损耗应该和直接使用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 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         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 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的优势就更加明显了。

4

总结

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

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

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

1、如果只是简单的字符串拼接,考虑直接使用"+"即可。

2、如果是在for循环中进行字符串拼接,考虑使用StringBuilder和StringBuffer。

3、如果是通过一个集合(如List)进行字符串拼接,则考虑使用StringJoiner。

4、如果是对一组数据进行拼接,则可以考虑将其转换成Stream,并使用StringJoiner处理。


●编号917,输入编号直达本文

●输入m获取文章目录

推荐↓↓↓

程序员求职面试

更多推荐25个技术类公众微信

涵盖:程序人生、算法与数据结构、黑客技术与网络安全、大数据技术、前端开发、Java、Python、Web开发、安卓开发、iOS开发、C/C++、.NET、Linux、数据库、运维等。

c++ 字符串拼接_字符串拼接新姿势:StringJoiner相关推荐

  1. JAVA的MySQL字符串拼接_字符串的拼接-MYSQL

    SQL允许两个或者多个字段之间进行计算,字符串类型的字段也不例外.比如我们需要以"工号+姓名"的方式在报表中显示一个员工的信息,那么就需要把工号和姓名两个字符串类型的字段拼接计算: ...

  2. delphi 字符串占用空间_字符串在Python内部是如何省内存的

    起步 Python3 起,str 就采用了 Unicode 编码(注意这里并不是 utf8 编码,尽管 .py 文件默认编码是 utf8 ). 每个标准 Unicode 字符占用 4 个字节.这对于内 ...

  3. mongodb 字符串 截取_字符串截取

    字符串: 一:substr() substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符. stringObject.substr(start,length) 参数描述 star ...

  4. java字符串拼接_字符串拼接,什么时候会走StringBuilder?

    ☞ 程序员进阶必备资源免费送「21种技术方向!」 ☜ 粉丝福利: 专属优惠码4折优惠,当当网买书满400-230(点击查看) 前言 最近在突然想到了 String 字符串拼接问题,于是做了一个 dem ...

  5. ++递归 字符串全排列_字符串/链表问题合集

    1.全排列 可视作一个所有元素交换的问题 # 输入一个字符串,打印出该字符串中字符的所有排列. # 例如输入字符串abc,则输出由字符a.b.c 所能排列出来的所有字符串 # abc.acb.bac. ...

  6. python字符串常用方法_字符串常用方法

    在使用字符串的时候通过使用一些方法能够更方便我们进行字符串的操作,我们来挑选一些常用的方法来进行讲解,其中基础方法包含count()方法.find()方法和index()方法,然后我们分为测试方法.修 ...

  7. java对字符串归一化_字符串归一化

    5 import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc=ne ...

  8. java 字符串 大括号_字符串解析其中的嵌套大括号

    从字符串中解析出 ${****},其中{}中间可能还有大括号. /*算法1: * 1.寻找${,没找到,直接返回空列表 * 2.找到${,从${中的$所在索引位置向后找第一个} * 3.在${和其后第 ...

  9. python输出字符串居中_字符串函数第一个大写以及字符串居中显示打印金字塔

    此课程与<清华编程高手.尹成.带你实战python入门>大体相同,只需购买其中的一门课程. 本课程由清华大学尹成老师录制,课程的特色在于讲解原理的同时引入了每个程序员都热衷的黑客技术.py ...

最新文章

  1. java例7_Java中单例七种写法(懒汉、恶汉、静态内部类、双重检验锁、枚举)
  2. 14.grafana导入导出;Grafana的安装和Influxdb数据源配置
  3. spingMVC拦截器 -单个、多个、设想
  4. 实验一 Linux开发环境的配置 20145213祁玮 20145222黄亚奇
  5. VBA实战技巧精粹010:如何快速选定工作表及Option Base 1
  6. ClearCase Overview
  7. 如何启用计算机睡眠功能,台式机睡眠如何开启
  8. 100层楼和两个玻璃球的问题
  9. bootloader相关
  10. 关于 TRTC (实时音视频通话模式)在我司的实践
  11. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛) 题解
  12. libnet/libnids库函数介绍
  13. Android 应用清单简介1
  14. 【分层强化学习】HAC源码解读
  15. 浅谈SAP公有云:S4 HANA Cloud
  16. Value Use User
  17. 周末读书|《大众天文学》:少年,追星吗?
  18. MySQL 系统表损坏导致xtrabackup备份失败Cannot open filepath
  19. P1644 跳马问题
  20. 钛资本研究院:创业型公司债权融资的几个基本场景

热门文章

  1. 4字节 经纬度_java 获取本机经纬度
  2. 实验项目 3-4:一元多项式的乘法与加法运算
  3. 电子计算机职专东校区在哪,自贡计算机电子信息职业技术学校位置在哪儿
  4. java stringutils_Java 笔记----- StringUtils 拼接字符
  5. 【算法设计与分析】09 递推方程与算法分析
  6. Unity3D性能优化之Draw Call Batching
  7. 逆向映射是干嘛的anon_vma, vma, anon_vma_chain
  8. Linux的#和$区别
  9. WdatePicker显示乱码
  10. URLEncoder编码